原生JavaScript实现焦点轮播图

通过学习,我理解了图片轮播原理,学习了setTimeout()、setInterval()函数设置定时器与清除定时器clearInterval()函数,使用函数递归实现图片滑动切换,采用辅助图片实现图片无限滚动等编程技巧。

一、焦点图轮播特效之原理

这个焦点图轮播特效将运用到了平时学习中的知识,例如,DOM操作、定时器、事件处理、JS动画、函数递归还有无线滚动等等。
其实焦点图轮播特效的原理十分简单,就是通过控制存放图片的列表里面的left值来显示图片。
HTML结构大致分为以下部分:

![](img\5.jpg) ![](img\1.jpg) ![](img\2.jpg) ![](img\3.jpg) ![](img\4.jpg) ![](img\5.jpg) ![](img\1.jpg)
  • 一个父容器container,父容器里面有一个图片列表list还有一个按钮buttons,再加上两个代表左右箭头的a标签;
  • javascript: 是一个伪协议,是是表示在触发a标签默认动作时,执行一段javascript代码,而javascript:;表示什么都不执行,这样点击a标签没有任何反应;
  • 为了实现无限滚动,在第一张图片之前加入第五张图片的附属图,在第五张图片之后加入第一张图片的附属图,实得在滚动的过程中,不会出现延迟现象;
二、焦点图轮播特效之样式布局

具体的CSS代码如下:


  • 其中将父容器里面的overflow属性设置为:hidden,并且将position设置为:relative,因为子元素list和buttons都是相对于父容器来定位的;
  • 其中里面涉及到了z-index属性:设置元素的堆叠顺序。元素可拥有负的z-index属性值,z-index仅仅能在定位元素上奏效,拥有更高层叠顺序的元素总是位于更低元素的前面;
三、焦点图轮播特效之箭头切换

接下来就进入JS部分的编写,首先必须是页面加载完毕才能执行相关的JS代码,所以必须写在window.onload = function(){}中,接下来先取得相关的容器和标签,如下:

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");
}

然后要做到点击箭头就能切换,就必须给箭头元素绑定一个点击事件,通过点击箭头,来改变list里面style属性中的left值,从而实现图片的切换

prev.onclick = function(){
      list.style.left = parseInt(list.style.left) - 600 + 'px';
}
next.onclick = function(){
     list.style.left = parseInt(list.style.left) + 600 + 'px';
}

因为两个点击事件里面的语句十分相似,所以就将它们封装在一个名为animate()的函数中,只需要传进一个偏移量就可以了,如下

 function animate(offset) {
     list.style.left = parseInt(list.style.left) + offset + 'px';
}
prev.onclick = function(){
      animate(-600);
}
next.onclick = function(){
     animate(600);
}
四、焦点图轮播特效之无限滚动

在上一节,我们已经实现了箭头的切换,但是会有一个问题,当切换到最左边,或者最右边时,会出现空白页,因为当滚动到第五张图片的附属图时,此时的left值为0,当继续往左切换时,就会大于0,当滚动到第一张图片的附属图时,此时的left值为-4200,当继续往右切换时,就会小于-4200,所以会出现空白现象;我们要达到的效果是,当滚动到第一张图片的附属图时,此时将它的left值设置回-600,当滚动到第五张图片的附属图时,将left值设置回-3000,才能达到无限滚动的效果,具体代码如下:

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';
    }
}

此时就可以实现无限滚动的效果了,这个时候,我们还需要加上小圆点的切换功能,这时候我们需要再引进一个变量index,来显示当前显示的是第几张图片,初始值为1;并且增加一个函数专门来亮起小圆点,如下:

function showButtons(){
       buttons[index-1].className = "on";
}

每点击一下左箭头,index的值就要减1,每点击一下右箭头,index的值就加1,如下:

prev.onclick = function(){
      index -= 1;
      showButtons();
      animate(-600);
}
next.onclick = function(){
     index += 1;
     showButtons();
     animate(600);
}

但是这个时候会发现,以前的按钮没有关闭,而是全都亮了起来,此时就要改进一下showButtons()函数,在亮起当前按钮的同时,将之前的按钮至灰色,代码如下:

function showButtons(){
       for(var i = 0; i < buttons.length; i++) {
             if(buttons[i].className == "on") {
                  buttons[i].className  = "";
                  break;
             }
      }
       buttons[index-1].className = "on";
}

还需要对index的值进行限制,不能让它无限的减下去,或者加上去,修改后的代码如下:

prev.onclick = function(){
      if(index == 5) {
          index = 1;
      } else {
        index -= 1;
    }
       showButtons();
       animate(-600);
}
next.onclick = function(){
     if(index == 1) {
        index = 5;
     } else {
        index += 1;
    }
    showButtons();
    animate(600); 
}
五、焦点图轮播特效之按钮切换

实现完了箭头的切换,接下来就要实现按钮的切换了,就是要分别给buttons数组里面的每个元素添加一个点击事件,跟箭头切换不同的是,按钮切换的偏移量需要计算,有可能跨几幅图片切换,还有,每张图片里面有个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;//更新index值
           showButton();
    }
}
  • 这里面有一个点需要注意,span标签里面index属性是属于自定义属性,不能通过点表示法来取得,所以要使用getAttribute()方法来获取,即能取自定义属性,又能取自身有的属性;

此时还有一些需要优化的地方,当我位于当前图片的时候,再点击当前按钮,后台还会执行,但是我们的理想情况应该是,位于当前图片的时候,再点击当前按钮,就应该不做任何事情,加一个判断语句,优化后的代码如下:

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;//更新index值
           showButton();
    }
}
六、焦点轮播图之动画函数

在进行图片的切换过程中,图片是缓慢的移动切换的,而不是一张图片一张图片的切换过去,这不是我们想要的效果,这里就涉及到了javascript中的动画效果和函数;
它的原理是在切换的过程中,不断地进行一小段的位移,直到达到目标值,清楚了原理,接下来就来写代码:
我们增加了位移总时间的变量、位移间隔还有计算出每次的位移量,并且定义了一个位移函数go(),当每次的位移量小于0并且left大于新的left目标值时,还有一种情况是,每次的位移量大于0并且left小于新的left目标值时,left值就等于left加上每次的位移量,然后调用setTimeout函数不断地递归调用,直到达到目标值;

 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) || (speemd >0 && parseInt(list.style.left) < newLeft)) {
                    list.style.left = parseInt(list.style.left) + speed + '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();
           }
  • 这里要注意的是,setTimeout()方法接受两个参数,一个执行的函数代码,一个间隔,函数会在这个间隔后执行一次,不会重复执行,但是因为调用的是自身,所以相当于递归不断地重复执行;
七、焦点图轮播特效之自动播放

我们会注意到,当我们把鼠标移出图片列表时,图片会自动切换,当把鼠标移进去时,就会停止自动切换,这里,我们就需要引入两个函数:play()还有stop()函数,并且为container父容器添加两个事件:onmouseover还有onmouseout,具体的代码如下:

       function play(){
            timer = setInterval(function(){
                    next.onclick();
                },1500);
           }
      function stop(){
      clearInterval(timer);
      }
      container.onmouseover = stop;
      container.onmouseout = play;
      play();

还重新定义了一个时间变量timer,并且执行setInterval方法,经过间隔时间不断地执行函数代码,然后停止函数里面,就清楚调这个时间变量timer;

你可能感兴趣的:(原生JavaScript实现焦点轮播图)