原生js图片轮播效果实现代码
现在很多javascript的插件都可以实现图片轮播的功能,这篇文章,主要是通过这个domo来解析javascript图片轮播的原理。
老规矩,先上代码。至于代码中的图片,随便找三张即可,最核心的还是理解其思想。
html:
<!DOCTYPEhtml> <html> <head> <metacharset="utf-8"/> <title>滚动图</title> <linkrel="stylesheet"type="text/css"href="css/scroll.css"/> </head> <body> <divid="wrapper"> <divid="box"> <imgsrc="img/banner0.png"/> <imgsrc="img/banner1.png"/> <imgsrc="img/banner2.png"/> </div> <divid="pointer"> <spanclass="active"></span> <span></span> <span></span> </div> </div> <scriptsrc="js/scroll.js"type="text/javascript"charset="utf-8"></script> </body> </html>
css:
*{ margin:0; padding:0; } #wrapper{ position:relative; width:1200px; margin:50pxauto; overflow:hidden; } #pointer{ clear:both; position:absolute; right:500px; bottom:15px; width:180px; height:2px; } #pointerspan{ display:block; box-sizing:border-box; float:left; width:50px; height:1.5px; margin-right:10px; border-radius:.5px; background:#fff; opacity:.5; -webkit-opacity:.5; -moz-opacity:.5; filter:alpha(opacity=50); } #pointer.active{ opacity:.8; -webkit-opacity:.8; -moz-opacity:.8; filter:alpha(opacity=80); } #box{ position:relative; width:3600px; clear:both; } img{ display:block; float:left; width:1200px; height:337px; }
javascript:
window.onload=function(){ //获取装图片的盒子 varbox=document.getElementById('box'); //获取装页码的盒子 varpointer=document.getElementById('pointer'); //获取盒子中的所有图片 varimglist=box.getElementsByTagName('img') //获取盒子中的所有页码 varpointerList=pointer.getElementsByTagName('span'); //图片的宽度,正负用于左右的循环 varn=-1200; //增加一倍的图片用于循环 box.innerHTML=box.innerHTML+box.innerHTML; //设置盒子的宽 box.style.width=imglist[0].offsetWidth*imglist.length+"px"; vartimer=null; timer=setInterval(function(){ scroll(box,n,pointerList); },3000); box.onmouseover=function(){ clearInterval(timer); } pointer.onmouseover=function(){ clearInterval(timer); } box.onmouseout=function(){ timer=setInterval(function(){ //console.log(newDate()); scroll(box,n,pointerList); },3000); } //设置页码的点击事件 for(vari=0;i<pointerList.length;i++){ pointerList[i].index=i;//设置一个参数,用下面调用某个页码 //如果不设置参数,在调用页码的时候会直接调用最后一个,因为我们使用了循环 pointerList[i].onclick=function(){ for(varj=0;j<pointerList.length;j++){ pointerList[j].className='';//清空激活的class } move(box,n*(this.index));//移动图片 this.className='active';//激活点击的页码 } } } /** *循环滚动函数 *@param{Object}box *@param{Object}n */ functionscroll(box,n,page){ //判断是否到达临界点,即box的中间部分 if(box.offsetLeft<=-box.offsetWidth/2){ box.style.left="0px";//重新从头开始 console.log('0'); } if(box.offsetLeft%n!=0){ //因为在我们切换浏览器标签页或者切换去其他软件界面的时候, //会影响到setInterval,有时候setInterval会增加好几秒,在这里我们必须加一个判断 //只有当它走完了一个整个的图片宽度时,我们才进行下一次滚动。 } else{ pageScroll(box,n,page); move(box,n+box.offsetLeft); } } /** *滚动页码函数 *@param{Object}box *@param{Object}n *@param{Object}page */ functionpageScroll(box,n,page){ //直接通过图片盒子的定位判断页码值,但是此时的页码值是滚动之前的,所以后面的值要+1使用 varindex=Math.abs(box.offsetLeft/n); console.log(index); for(vari=0;i<page.length;i++){ page[i].className=''; } //判断是不是最后一页,是最后一页的话+1要变成0; if(index<page.length-1){ page[index+1].className='active'; } else{ page[0].className='active'; } } /** *变速移动 *@param{Object}ele *@param{Object}target */ functionmove(ele,target){ clearInterval(ele.timer); console.log(newDate()); ele.timer=setInterval(function(){ varstep=(target-ele.offsetLeft)/10; step=step>0?Math.ceil(step):Math.floor(step); if(target==ele.offsetLeft){ console.log(newDate()); clearInterval(ele.timer); } else{ ele.style.left=ele.offsetLeft+step+"px"; } },30); }
html和css部分依旧比较简单,直接跳过。javascript部分的代码注释写的也比较详细,下面主要讲解逻辑部分。
图片滚动的原理是利用setInterval函数进行背景图片的不断循环。为了避免图片循环的过程中出现间断,首先是在javascript中进行图片的复制(增加一倍),然后当到达临界点时,瞬间将图片移动到初始的位置,然后开始下一轮循环。
在这个domo中,主要包含四个函数:
1、外层控制间隔时间的函数。这个比较容易理解,通过setInterval函数每隔几秒循环执行一次图片滚动的函数。
2、中间层滚动函数。判断图片盒子是否到达临界点,判断当前状态是否符合进入下一次滚动(这个条件主要是为了防止切换界面对setInterval函数的影响,具体原因在最后)。
3、中间层页码滚动函数。基本没有难点,主要是理解页码为什么+1即可。
4、图片滚动函数。这个在之前写过的一篇文章有详细讲解,不再赘述,参考:https://www.nhooo.com/article/95211.htm
最后,一点关于setInterval底层机制的扩展。
我们内层函数的执行事件正常情况下为1-2s(测试过),而外层的循环需要3s才进行一次,正常的情况是没有问题的。但是,当你切换界面的时候,浏览器就会对setInterval函数产生影响,此时执行事件的事件就会超过3面,在没移动结束的情况下开启另一个定时器进行下一次图片滚动,所以就会发生错乱。
javascript是单线程的,当你使用setInterval函数的时候并不是真正暂停,而是先挂起这个事件,继续执行下面的事件,而当这个事件要执行时,如果浏览器当前没有任务,那么它会立马执行,但是如果浏览器有任务,那么就会有一定的延迟,这也是为什么切换界面会对setInterval函数的时间产生影响。
(关于setInterval函数的理解如有错误,欢迎指正!如果大家想要深入理解,也可以去一些大神的博客看一下setInterval函数的文章)
精彩专题分享:jQuery图片轮播JavaScript图片轮播Bootstrap图片轮播
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。