原生JS焦点轮播图实现

来源:互联网 发布:中国银行网络金融 编辑:程序博客网 时间:2024/05/29 19:56

这是根据网上的教程写的,教程讲的调理很清晰,所以我想把它一步步写下来,算作是一篇笔记吧。脑子笨就要多看多写。奋斗

html结构和css样式

<!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 { float: left;}        #list div{ 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></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 style="background-color: #e4b9b9">1</div>        <div style="background-color: #e4b9b9">1</div>        <div style="background-color: #e460b6">2</div>        <div style="background-color: #e4e13f">3</div>        <div style="background-color: #4689e4">4</div>        <div style="background-color: #47e4ad">5</div>        <div style="background-color: #47e4ad">5</div>    </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>


实现原理

功能:点击左右箭头左右滑动显示不同图片,点击小按钮显示对应图片,鼠标移出图片范围实现自动播放。

技能点:DOM操作,定时器,函数递归,事件运用,JS动画,无限滚动

要实现一个完整功能的焦点轮播图效果,我们可以按照这几个步骤来进行:

  • 箭头切换
  • 无限滚动
  • 按钮切换
  • 函数动画
  • 自动播放

1. 箭头切换

    点击左右箭头,图片相应方向切换显示。

    代码片段1:

       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");                        next.onclick=function(){                list.style.left = parseInt(list.style.left) - 600 + "px";            }            prev.onclick=function(){                list.style.left = parseInt(list.style.left) + 600 + "px";            }            }
    图片容器list的left起始值是-600px,而每张图片的宽度也是600px,所以当我们点击next箭头时希望下一张图片显示就要给list.style.left减去600px;反方向的话就是加上600px;

    这里我们发现

listy.style.left = parseInt(list.style.left) + 600
    这个值其实我们可以放在一个函数里面来调用,减少代码量,称为封装。代码片段1可以重写为这样:

        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");                                    function animate(offset){            list.style.left = parseInt(list.style.left) + offset + "px";            }                        next.onclick=function(){            animate(-600);            }            prev.onclick=function(){            animate(600);            }        }
     这里我们创建了animate函数,给它一个offset参数,点击向前向后调用animate函数,实现图片的切换。

     到此为止箭头切换这一步就实现了,但是我们发现,当点击切换到最后一张图片再点击时,图片变成了空白,而我们需要切换到最后一张图片再点击时显示的是第一张图片,要实现这种功能,我们就需要进行 无限滚动操作。

2.  无限滚动

     这里只要弄清楚无限滚动的原理其实很简单,我们这个DEMO中为第一张和最后一张添加了与之相同的附属图。当list的偏移值小于-600,也就是当前图片为第一张图片再向前切换的时候,要实现无限滚动,只需要把最后一张图显示出来就好了,也就是说让list的偏移值为-3000就行了。所以,要实现无限滚动,animate方法需要这样改写:

            function animate(offset){                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";                }            }
      这时候左右切换基本就实现了,但我们发现左右切换的时候,这些小圆点按钮应该也随之对应切换,这里我们就需要添加新的方法showButton()

            var index=1;//用来存放当前显示的图片小圆点            function showButton(){ //给对应的小圆点添加class,而其他的小圆点去掉样式                for(var i=0;i<buttons.length;i++){                    if(buttons[i].className=="on"){                        buttons[i].className = "";                        break;                    }                }                buttons[index-1].className="on";            }
       在点击切换方法中这样调用

            next.onclick=function(){                if(index==5){  //当到第5张即最后一张图片时将index重置为1,即返回第一张图片                    index =1;                }else{                    index += 1;                }                showButton();            animate(-600);            }            prev.onclick=function(){                if(index==1){                    index =5;                }else{                    index -= 1;                }                showButton();            animate(600);            }
这样我们就是实现了无限滚动,并且小圆点也随之对应变化。而我们还希望当点击任意小圆点的时候也应该显示对应图片,这里我们就需要添加一个按钮切换方法。

3.   按钮切换

点击任意小圆点的时候也应该显示对应图片。

我们就需要判断点击的小圆点与图片的对应索引应该相同。这里我们需要注意,正常按顺序一张张切换的时候,每点击一次list的偏移量就加上或者减去600px;不按顺序的时候,list的偏移量就应该是: -600*(目标index值-当前index值)。

            for (var i = 0; i < buttons.length; i++) {                buttons[i].onclick = function () {                    var myIndex=parseInt(this.getAttribute("index"));                    var offset= -600 * (myIndex-index);                    animate(offset);                    index=myIndex;                    showButton();                }            }
这样按钮切换就基本完成,但是还有一点小BUG,点击当前小圆点的时候,图片又会刷新一遍,于是我们要做一些小改动:
            for (var i = 0; i < buttons.length; i++) {                buttons[i].onclick = function () {                    if(this.className=="on"){                        return;                    }                    var myIndex=parseInt(this.getAttribute("index"));                    var offset= -600 * (myIndex-index);                    animate(offset);                    index=myIndex;                    showButton();                }            }

到这里按钮点击切换就完成了。

4.   函数动画

 我们不希望切换的时候是整张图片而是慢慢的平滑的切换,这里就需要将动画函数进行改动:

           function animate(offset) {                var newLeft = parseInt(list.style.left) + offset;                var time=300;//位移总时间                var interval=10;//位移间隔时间                var speed=offset/(time/interval); //每次位移量                function go(){                    if((speed<0 && parseInt(list.style.left)>newLeft) ||(speed>0 && parseInt(list.style.left)<newLeft)){                        list.style.left = speed + parseInt(list.style.left) + "px";                        setTimeout(go,interval);//                    }                    else{                        list.style.left = newLeft + "px";                        if (newLeft > -600) {                            list.style.left = -3000 + "px";                        }                        if (newLeft < -3000) {                            list.style.left = -600 + "px";                        }                    }                }                go();            }
这里用到了递归函数的知识点,简单将就是在函数体内调用本函数。

当我们不停点击切换的时候,图片不停地切换,这样会造成卡顿的现象,我们需要进行改动,当一张图片完全显示以后才能再次点击切换,当每次动画结束时点击切换才会调用animate()方法。添加一个变量 animated初始值为flase;然后进行判断。

           var animated=false;           function animate(offset) {                animated=true;                var newLeft = parseInt(list.style.left) + offset;                var time=300;//位移总时间                var interval=10;//位移间隔时间                var speed=offset/(time/interval); //每次位移量                function go(){                    if((speed<0 && parseInt(list.style.left)>newLeft) ||(speed>0 && parseInt(list.style.left)<newLeft)){                        list.style.left = speed + parseInt(list.style.left) + "px";                        setTimeout(go,interval);//                    }                    else{                        animated=false;                        list.style.left = newLeft + "px";                        if (newLeft > -600) {                            list.style.left = -3000 + "px";                        }                        if (newLeft < -3000) {                            list.style.left = -600 + "px";                        }                    }                }                go();            }            next.onclick = function () {                if (animated) {                    return;                }                if (index == 5) {  //当到第5张即最后一张图片时将index重置为1,即返回第一张图片                    index = 1;                } else {                    index += 1;                }                showButton();                animate(-600);            }            prev.onclick = function () {                if (animated) {                    return;                }                if (index == 1) {                    index = 5;                } else {                    index -= 1;                }                showButton();                animate(600);            }            for (var i = 0; i < buttons.length; i++) {                buttons[i].onclick = function () {                    if (animated) {                        return;                    }                    if(this.className=="on"){                        return;                    }                    var myIndex=parseInt(this.getAttribute("index"));                    var offset= -600 * (myIndex-index);                    animate(offset);                    index=myIndex;                    showButton();                }            }
5.   自动播放

通常我们希望某些时候图片可以自动切换,我们就需要添加新的方法。

每隔固定时间自动点击切换按钮,这就是自动播放的原理。就需要用到定时器setInterval();

            var interval=3000;            var timer;            function play(){                timer=setInterval(function(){next.onclick();},interval);            }            function stop(){                clearInterval(timer);//清除定时器            }            container.onmouseover=stop;            container.onmouseout=play;            play();

这里我们发现了新的定时器setInterval,这和之前的setTimeout有什么区别呢?

setInterval在执行完一次代码之后,经过了那个固定的时间间隔,它还会自动重复执行代码

setTimeout只执行一次那段代码。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

完整焦点轮播图代码JS

     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 animated=false;            var interval=3000;            var timer;            function showButton() { //给对应的小圆点添加class,而其他的小圆点去掉样式                for (var i = 0; i < buttons.length; i++) {                    if (buttons[i].className == "on") {                        buttons[i].className = "";                        break;                    }                }                buttons[index - 1].className = "on";            }            function animate(offset) {                animated=true;                var newLeft = parseInt(list.style.left) + offset;                var time=300;//位移总时间                var interval=10;//位移间隔时间                var speed=offset/(time/interval); //每次位移量                function go(){                    if((speed<0 && parseInt(list.style.left)>newLeft) ||(speed>0 && parseInt(list.style.left)<newLeft)){                        list.style.left = speed + parseInt(list.style.left) + "px";                        setTimeout(go,interval);//                    }                    else{                        animated=false;                        list.style.left = newLeft + "px";                        if (newLeft > -600) {                            list.style.left = -3000 + "px";                        }                        if (newLeft < -3000) {                            list.style.left = -600 + "px";                        }                    }                }                go();            }            function play(){                timer=setInterval(function(){next.onclick();},interval);            }            function stop(){                clearInterval(timer);//清除定时器            }            next.onclick = function () {                if (animated) {                    return;                }                if (index == 5) {  //当到第5张即最后一张图片时将index重置为1,即返回第一张图片                    index = 1;                } else {                    index += 1;                }                showButton();                animate(-600);            }            prev.onclick = function () {                if (animated) {                    return;                }                if (index == 1) {                    index = 5;                } else {                    index -= 1;                }                showButton();                animate(600);            }            for (var i = 0; i < buttons.length; i++) {                buttons[i].onclick = function () {                    if (animated) {                        return;                    }                    if(this.className=="on"){                        return;                    }                    var myIndex=parseInt(this.getAttribute("index"));                    var offset= -600 * (myIndex-index);                    animate(offset);                    index=myIndex;                    showButton();                }            }            container.onmouseover=stop;            container.onmouseout=play;            play();        }


----------------------------------------------------------------------------------------------------------------------------------------------------------------------

到此为止,我们的这个焦点轮播图就算大功告成了。但是这中方法还是有一定的问题,我们必须为第一张和最后一张图添加对应的附属图,拓展性不是特别强。

第一次写,错误肯定会有,先草草结束吧。










0 0
原创粉丝点击