PC端网页特效-轮播图

1年前 (2021-09-25) 1049次浏览 已收录 0个评论

功能需求

  1. 点击右侧按钮一次,图片往左播放一张,左侧一样。
  2. 图片播放的同时,下面的小圆圈也跟随它一起变化。
  3. 点击小圆圈,可以播放相应图片。
  4. 鼠标不经过轮播图,轮播图也会自动播放图片。
  5. 鼠标经过轮播图,自动播放停止。

滚动图片的核心算法

  • 点击某个小圆圈,就让图片滚动,小圆圈的索引号乘以图片的宽度作为ul的移动距离
  • 声明一个变量,点击右侧按钮,自增1,让这个变量乘以图片宽度,就是ul的滚动距离

图片无缝滚动原理

  1. 把ul第一个li复制一份,放到ul的最后面
  2. 当图片滚动到克隆的最后一张图片时,让ul快速的、不做动画的跳到最左侧:left为0
  3. 同时num重新赋值为0,以便于开始新的滚动

点击右侧按钮,小圆圈会跟随变化

  • 声明一个全局变量circle,每次点击自增1,
  • 但是图片有5张,而小圆圈只有4个,所以加一个判断条件
  • 如果小圆圈下标circle == 4就重新复原为0

自动播放

  1. 添加一个定时器
  2. 自动播放,实际就类似于点击啦右侧按钮
  3. 手动调用事件arrow_r.click()

节流阀

防止轮播图按钮连续点击造成播放过快的问题

逻辑:

  • 当上一个函数动画内容执行完毕,再去执行下一个函数动画,达到让事件无法连续触发。

思路:

  • 利用回调函数,添加一个变量来控制,锁住函数和解锁函数。
开始设置一个变量 var flag=true;
if(flag){flag=false; 动画内容} //关闭了水龙头
利用回调函数当动画执行完毕后再flag=true 打开水龙头

案例

<script>
        var focus=document.querySelector('.focus');
        var arrow_l=document.querySelector('.arrow_l');
        var arrow_r=document.querySelector('.arrow_r');
        var ul=document.querySelector('ul');
        var ulli=ul.querySelector('li');
        var ol=document.querySelector('.circle');
        var focusWidth=ulli.offsetWidth;//图片宽度
        //鼠标经过focus,就停止自动播放
        focus.addEventListener('mouseenter',function(){
            clearInterval(timer);
        });
        focus.addEventListener('mouseleave',function(){
            timer = setInterval(function () {
                //手动调用点击事件
                arrow_r.click();
            }, 1500);
        })
        //动态生成小圆圈
        for(var i=0;i<ul.children.length;i++){
            var li = document.createElement('li');
            //记录当前小圆圈的索引号
            li.setAttribute('index',i);
            ol.appendChild(li);
            li.addEventListener('click',function(){
                //排他思想
                clearcurrent();
                this.className='current';
                //滚动图片的核心算法:点击某个小圆圈,就让图片滚动,小圆圈的索引号乘以图片的宽度作为ul的移动距离
                //点击小圆圈,移动ul,即移动图片
                //ul的移动距离=当前小圆圈的索引号 * 图片的宽度,负值
                var index=this.getAttribute('index');//拿到当前点击的索引号
                //当点击了某个小li,就要把这个li的索引号给num
                num=index;
                // 再给小圆圈的下标circle
                circle=num;
                animate(ul,-index*focusWidth);
            })
        }
        //首次是第一个显示小圆圈
        ol.children[0].className='current';
        //图片无缝滚动_克隆第一张图片:把ul第一个li复制一份,放到ul的最后面
        var first=ul.children[0].cloneNode(true);
        ul.appendChild(first);
        //点击右侧按钮
        // 声明一个变量,点击右侧按钮,自增1,让这个变量乘以图片宽度,就是ul的滚动距离
        var num=0;
        //点击右侧按钮,小圆圈会跟随变化:声明一个全局变量,控制小圆圈的播放
        var circle=0;
        var flag=true; //节流阀
        arrow_r.addEventListener('click',function(){
            if(flag){
                flag=false;//关闭节流阀
                //图片无缝滚动
                // 把ul第一个li复制一份,放到ul的最后面
                // 当图片滚动到克隆的最后一张图片时,让ul快速的、不做动画的跳到最左侧:left为0
                // 同时num重新赋值为0,以便于开始新的滚动
                //如果走到了最后复制的一张图片,此时ul要快速把left改为0
                if (num == ul.children.length - 1) {//此时孩子多一个复制的,所以要减去
                    ul.style.left = 0;
                    num = 0;//并且从0开始,下面会自增1,继而直接播放了第二张
                }
                num++;
                animate(ul, -num * focusWidth,function(){
                    flag=true;//动画内容执完毕后再执行回调函数,即打开节流阀
                });
                circle++;
                // 但是图片有5张,而小圆圈只有4个,所以加一个判断条件
                // 如果circle == 4 说明走到最后克隆的最后一个图片啦,所以就重新复原为0
                if (circle == ol.children.length) {
                    circle = 0;
                }
                clearcurrent();
                ol.children[circle].className = 'current';
            }
        })
        //左侧按钮
        arrow_l.addEventListener('click', function () {
                if(flag){
                    flag=false;
                    if (num == 0) {
                        num = ul.children.length - 1;//从4开始,下面会自减1,继而直接播放了第3张
                        ul.style.left = -num * focusWidth + 'px';
                    }
                    num--;
                    animate(ul, -num * focusWidth, function () {
                        flag = true;
                    });
                    circle--;
                    // 如果circle < 0 说明是第四张图片,则小圆圈要改为第四个小圆圈
                    if (circle < 0) {
                        circle = ol.children.length - 1;
                    }
                    clearcurrent();
                    ol.children[circle].className = 'current';
                }
            })
        function clearcurrent(){
            for(var i=0;i<ul.children.length-1;i++){
                ol.children[i].className='';
            }
        }
        function animate(obj, target,callback) {
                clearInterval(obj.timer);
                obj.timer = setInterval(function() {
                //把步长值改为整数(往上取整),不然小数会出现走不到目标位置的问题
                var step = (target - obj.offsetLeft) / 10;
                //当步长大于0就往上取整(即取大值的整数),小于0就往下取整(即取小值的整负数)
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
                if (obj.offsetLeft == target) {
                    clearInterval(obj.timer);
                    if(callback){
                        callback();
                    }
                }
                obj.style.left = obj.offsetLeft + step + 'px';
            }, 15);
        }
        //自动播放轮播图
        var timer=setInterval(function(){
            //手动调用点击事件
            arrow_r.click();
        },1500);
    </script>
结果演示

渣渣龙, 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:PC端网页特效-轮播图
喜欢 (1)

您必须 登录 才能发表评论!