在团队带人,突然被人问到轮播图如何实现,进入前端领域有一年多了,但很久没自己写过,一直是用大牛写的插件,今天就写个简单的适合入门者学习的小教程。当然,轮播图的实现原理与设计模式有很多种,我这里讲的是用面向过程函数式编程去实现,相对于面向对象设计模式,代码难免会显得臃肿冗余。但没有面向对象的抽象却很适合新手理解与学习。已经在BAT的同学看到希望少喷点。另外可以多提意见。
轮播图的原理:
一系列的大小相等的图片平铺,利用CSS布局只显示一张图片,其余隐藏。通过计算偏移量利用定时器实现自动播放,或通过手动点击事件切换图片。
Html布局
首先父容器container存放所有内容,子容器list存在图片。子容器buttons存放按钮小圆点。
<div id="container"> <div id="list" style="left: -600px;"> <img src="img/5.jpg" alt="1" /> <img src="img/1.jpg" alt="1" /> <img src="img/2.jpg" alt="2" /> <img src="img/3.jpg" alt="3" /> <img src="img/4.jpg" alt="4" /> <img src="img/5.jpg" alt="5" /> <img src="img/1.jpg" alt="5" /> </div> <div id="buttons"> <span index="1" class="on"></span> <span index="2"></span> <span index="3"></span> <span index="4"></span> <span index="5"></span> </div> <a href="javascript:;" id="prev" class="arrow"><</a> <a href="javascript:;" id="next" class="arrow">></a> </div>
优化,无缝滚动。
当你从最后一张图切换回第一张图时,有很大空白,利用两张辅助图来填补这个空白。
这里补充下无缝滚动,直接看代码,复制最后一张图片放置第一张图片前,同时复制第一张图片放置最后一张图片的后面。并且,将第一张图片辅助图(实际上是实际显示的第5张图片隐藏起来,故设置style="left: -600px;")
CSS修饰
1、对盒子模型,文档流的理解,绝对定位问题。
2、注意list的overflow:hidden;只显示窗口的一张图片,把左右两边的都隐藏起来。
3、确保buttons中每个span所在层置顶,将其设置为最顶端。(z-index:999)
* {margin: 0;padding: 0;text-decoration: none;}body {padding: 20px;}#container {width: 600px;height: 400px;border: 3px solid #333;overflow: hidden;position: relative;}#list {width: 4200px;height: 400px;position: absolute;z-index: 1;}#list img {width: 600px;height: 400px;float: left;}#buttons {position: absolute;height: 10px;width: 100px;z-index: 2;bottom: 20px;left: 250px;}#buttons span {cursor: pointer;float: left;border: 1px solid #fff;width: 10px;height: 10px;border-radius: 50%;background: #333;margin-right: 5px;}#buttons .on {background: orangered;}.arrow {cursor: pointer;display: none;line-height: 39px;text-align: center;font-size: 36px;font-weight: bold;width: 40px;height: 40px;position: absolute;z-index: 2;top: 180px;background-color: RGBA(0, 0, 0, .3);color: #fff;}.arrow:hover {background-color: RGBA(0, 0, 0, .7);}#container:hover .arrow {display: block;}#prev {left: 20px;}#next {right: 20px;}
Js
首先我们先实现出手动点击左右两个箭头切换图片的效果:
window.onload = function() {var list = document.getElementById('list');var prev = document.getElementById('prev');var next = document.getElementById('next');function animate(offset) {//获取的是style.left,是相对左边获取距离,所以第一张图后style.left都为负值,//且style.left获取的是字符串,需要用parseInt()取整转化为数字。var newLeft = parseInt(list.style.left) + offset;list.style.left = newLeft + 'px';}prev.onclick = function() { animate(600);}next.onclick = function() { animate(-600);}}
运行后我们会发现,一直点击右箭头 ,会出现空白,而且,不能回到第一张图片。要点击左箭头才能回到第一张图片。
利用谷歌浏览器F12,原因是我们利用偏移量left来获取图片,当看到left值小于3600时,因为没有第8张图片就出现空白,所以这里我们需要对偏移量做一个判断。
在animate函数里加上这么一段:
if(newLeft<-3000){list.style.left = -600 + 'px';}if(newLeft>-600){list.style.left = -3000 + 'px';}
好,运行一下,没问题了。轮播图,顾名思义,是自己会动的图片,这个时候我们需要用到浏览器的内置对象定时器。
对于定时器,有必要说明一下setInterval()跟setTimeout的区别了。简单来说,setInterval()执行多次,setTimeout()只执行一次。
更具体的用法可以点击链接查看区别:window.setInterval window.setTimeout 。
这里我们是用setInterval(),因为我们的图片需要循环滚动。插入下面
var timer;function play() {timer = setInterval(function () {prev.onclick()}, 1500)}play();
运行,ok!
但是,当我们想仔细看某一张图片时候,要把图片停住,我们清楚定时器就可以了,这里用到window.clearInterval 这个方法。
这里,我们需要对其DOM操作,需要获取整个轮播图区域;
var container = document.getElementById('container');function stop() {clearInterval(timer);}container.onmouseover = stop;container.onmouseout = play;
但这里,一个轮播图基本算完成了,有同学・会问,那么简单。看到图片下面的那一排小圆点没。我给你加功能了。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
这里是升级版:
var buttons = document.getElementById('buttons').getElementsByTagName('span');var index = 1;function buttonsShow() {//这里需要清除之前的样式for (var i = 0; i < buttons.length; i++) {if (buttons[i].className == 'on') {buttons[i].className = '';}}//数组从0开始,故index需要-1buttons[index - 1].className = 'on';}prev.onclick = function() {index -= 1;if (index < 1) {index = 5;}buttonsShow();animate(600);}next.onclick = function() {//由于上边定时器的作用,index会一直递增下去,我们只有5个小圆点,所以需要做出判断index += 1;if (index > 5) {index = 1;}buttonsShow();animate(-600);}
现在看起来正常多了吧,但我们想实现通过鼠标任意点击其中一个小圆点,切换到相应的图片,原理同样,我们还是需要通过偏移量去找到对应的图片。
for (var i = 0; i < buttons.length; i++) {buttons[i].onclick = function() {//优化,当前图片点击当前的小圆点不执行以下代码。if (this.className == "on") {return;}/* 偏移量获取:这里获得鼠标移动到小圆点的位置,用this把index绑定到对象buttons[i]上,去谷歌this的用法 *//* 由于这里的index是自定义属性,需要用到getAttribute()这个DOM2级方法,去获取自定义index的属性*/var clickIndex = parseInt(this.getAttribute('index'));var offset = 600 * (clickIndex - index);animate(offset);//存放鼠标点击后的位置,用于小圆点的正常显示index = clickIndex;buttonsShow();}}
大家,可能发现了,这个轮播图有点奇怪,不中规中矩,它是向左切换的,改写一下:
function play() {//将轮播图换成向右切换图片timer = setInterval(function () {next.onclick();}, 2000)} <!DOCTYPE html><html><head><meta charset="UTF-8"><title></title><style type="text/css">* {margin: 0;padding: 0;text-decoration: none;}body {padding: 20px;}#container {width: 600px;height: 400px;border: 3px solid #333;overflow: hidden;position: relative;}#list {width: 4200px;height: 400px;position: absolute;z-index: 1;}#list img {width: 600px;height: 400px;float: left;}#buttons {position: absolute;height: 10px;width: 100px;z-index: 2;bottom: 20px;left: 250px;}#buttons span {cursor: pointer;float: left;border: 1px solid #fff;width: 10px;height: 10px;border-radius: 50%;background: #333;margin-right: 5px;}#buttons .on {background: orangered;}.arrow {cursor: pointer;display: none;line-height: 39px;text-align: center;font-size: 36px;font-weight: bold;width: 40px;height: 40px;position: absolute;z-index: 2;top: 180px;background-color: RGBA(0, 0, 0, .3);color: #fff;}.arrow:hover {background-color: RGBA(0, 0, 0, .7);}#container:hover .arrow {display: block;}#prev {left: 20px;}#next {right: 20px;}</style><script type="text/javascript">/* 知识点: *//* this用法 *//* DOM事件 *//* 定时器 */window.onload = function () {var container = document.getElementById('container');var list = document.getElementById('list');var buttons = document.getElementById('buttons').getElementsByTagName('span');var prev = document.getElementById('prev');var next = document.getElementById('next');var index = 1;var timer;function animate(offset) {//获取的是style.left,是相对左边获取距离,所以第一张图后style.left都为负值,//且style.left获取的是字符串,需要用parseInt()取整转化为数字。var newLeft = parseInt(list.style.left) + offset;list.style.left = newLeft + 'px';//无限滚动判断if (newLeft > -600) {list.style.left = -3000 + 'px';}if (newLeft < -3000) {list.style.left = -600 + 'px';}}function play() {//重复执行的定时器timer = setInterval(function () {next.onclick();}, 2000)}function stop() {clearInterval(timer);}function buttonsShow() {//将之前的小圆点的样式清除for (var i = 0; i < buttons.length; i++) {if (buttons[i].className == "on") {buttons[i].className = "";}}//数组从0开始,故index需要-1buttons[index - 1].className = "on";}prev.onclick = function () {index -= 1;if (index < 1) {index = 5}buttonsShow();animate(600);};next.onclick = function () {//由于上边定时器的作用,index会一直递增下去,我们只有5个小圆点,所以需要做出判断index += 1;if (index > 5) {index = 1}animate(-600);buttonsShow();};for (var i = 0; i < buttons.length; i++) {buttons[i].onclick = function () {//优化,当前图片点击当前的小圆点不执行以下代码。if (this.className == "on") {return;}/* 这里获得鼠标移动到小圆点的位置,用this把index绑定到对象buttons[i]上,去谷歌this的用法 *//* 由于这里的index是自定义属性,需要用到getAttribute()这个DOM2级方法,去获取自定义index的属性*/var clickIndex = parseInt(this.getAttribute('index'));var offset = 600 * (clickIndex - index); //这个index是当前图片停留时的indexanimate(offset);index = clickIndex; //存放鼠标点击后的位置,用于小圆点的正常显示buttonsShow();}}container.onmouseover = stop;container.onmouseout = play;play();}</script></head><body><div id="container"><div id="list" style="left: -600px;"><img src="img/5.jpg" alt="1"/><img src="img/1.jpg" alt="1"/><img src="img/2.jpg" alt="2"/><img src="img/3.jpg" alt="3"/><img src="img/4.jpg" alt="4"/><img src="img/5.jpg" alt="5"/><img src="img/1.jpg" alt="5"/></div><div id="buttons"><span index="1" class="on"></span><span index="2"></span><span index="3"></span><span index="4"></span><span index="5"></span></div><a href="javascript:;" id="prev" class="arrow"><</a><a href="javascript:;" id="next" class="arrow">></a></div></body></html>
以上所述是小编给大家介绍的简单的JS轮播图代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!
新闻热点
疑难解答