想桉. 2022-08-03 11:17 采纳率: 85.7%
浏览 94
已结题

这个滑动轮播图 点下一张按钮 点到最后一张直接跳转到第一张 没有动画效果


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style type="text/css">
      * {
        margin: 0;
        padding: 0;
      }

      #outer {
        width: 520px;
        height: 333px;
        margin: 50px auto;
        background-color: greenyellow;
        padding: 10px 0;
        position: relative;
        overflow: hidden;
      }

      #imgList {
        list-style: none;
        position: absolute;
        left: 0px;
      }

      #imgList li {
        float: left;
        margin: 0 10px;
      }

      #navDiv {
        position: absolute;
        bottom: 15px;
      }

      #navDiv a {
        float: left;
        width: 15px;
        height: 15px;
        background-color: red;
        margin: 0 5px;
        opacity: 0.5;
        /*兼容IE8透明*/
        filter: alpha(opacity=50);
      }

      #navDiv a:hover {
        background-color: black;
      }
      .prev,
      .next {
        width: 20px;
        height: 80px;
        position: absolute;
        background-color: aqua;
        bottom: 50%;
      }
      .prev {
        left: 0;
      }
      .next {
        right: 0;
      }
    </style>
  </head>
  <body>
    <!-- 创建一个外部的div,来作为大的容器 -->
    <div id="outer">
      <!-- 创建一个ul,用于放置图片 -->
      <ul id="imgList">
        <li>< img src="img/1.jpg" /></li>
        <li>< img src="img/2.jpg" /></li>
        <li>< img src="img/3.jpg" /></li>
        <li>< img src="img/4.jpg" /></li>
        <li>< img src="img/5.jpg" /></li>
        <li>< img src="img/1.jpg" /></li>
      </ul>
      <!--创建导航按钮-->
      <div id="navDiv">
        <a href=" "></a >
        <a href="javascript:;"></a >
        <a href="javascript:;"></a >
        <a href="javascript:;"></a >
        <a href="javascript:;"></a >
      </div>

      <div class="prev">上一张</div>
      <div class="next">下一张</div>
    </div><script>
      let imgList = document.getElementById("imgList");
      let imgArr = document.getElementsByTagName("img");
      let prev = document.querySelector(".prev");
      let next = document.querySelector(".next");
      //设置ul的宽度
      imgList.style.width = imgArr.length * 520 + "px";

      // 设置导航栏按钮居中
      let navDiv = document.getElementById("navDiv");
      let outer = document.getElementById("outer");
      navDiv.style.left = (outer.offsetWidth - navDiv.offsetWidth) / 2 + "px";

      let index = 0;
      //获取所有的a
      var allA = document.getElementsByTagName("a");
      //设置默认选中的效果
      allA[index].style.backgroundColor = "black";
      for (var i = 0; i < allA.length; i++) {
        allA[i].num = i;
        allA[i].onclick = function () {
          clearInterval(time);
          index = this.num;
          setA();
          move(imgList, "left", -520 * index, 20, function () {
            auttoChang();
          });
        };
      }
      //上一张
      prev.onclick = function () {
        clearInterval(time);
        index--;
        index %= imgArr.length;
        if (index == -1) {
          index = imgArr.length - 1;
          imgList.style.left = -520 * index + "px";
          index = imgArr.length - 2;
        }
        setA();
        move(imgList, "left", -520 * index, 20, function () {
          auttoChang();
        });
      };
      //下一张
      next.onclick = function () {
        clearInterval(time);
        index++;
        index %= imgArr.length;
        if (index == imgArr.length - 1) {
          index = 0;
          imgList.style.left = -520 * index + "px";
        }
        setA();
        move(imgList, "left", -520 * index, 20, function () {
          auttoChang();
        });
      };
      var time = null;
      auttoChang();

      //小方块样式设置
      function setA() {
        if (index == imgArr.length - 1) {
          index = 0;
          imgList.style.left = 0;
        }
        for (var i = 0; i < allA.length; i++) {
          allA[i].style.backgroundColor = "";
        } //将选中的a设置为黑色
        allA[index].style.backgroundColor = "black";
      }

      //定时器动画
      function auttoChang() {
        time = setInterval(function () {
          index++;
          index %= imgArr.length;
          move(imgList, "left", -520 * index, 20, function () {
            setA();
          });
        }, 2000);
      }

      document.addEventListener("visibilitychange", function () {
        if (document.visibilityState === "hidden") {
          clearInterval(time);
        } else {
          auttoChang();
        }
      });

      //封装动画函数
      function getStyle(obj, name) {
        if (window.getComputedStyle) {
          //正常浏览器的方式,具有getComputedStyle()方法
          return getComputedStyle(obj, null)[name];
        } else {
          //IE8的方式,没有getComputedStyle()方法
          return obj.currentStyle[name];
        }
      }
      /*
       * 参数:
       *    obj:要执行动画的对象
       *    attr:要执行动画的样式,比如:left top width height
       *    target:执行动画的目标位置
       *    speed:移动的速度(正数向右移动,负数向左移动)
       *    callback:回调函数,这个函数将会在动画执行完毕以后执行
       */
      function move(obj, attr, target, speed, callback) {
        clearInterval(obj.timer);
        let curret = parseInt(getStyle(obj, attr));
        if (curret > target) {
          speed = -speed;
        }
        ////向执行动画的对象中添加一个timer属性,用来保存它自己的定时器的标识
        obj.timer = setInterval(function () {
          //把字符串里有效数字提取出来 转换为数字
          let oldvalue = parseInt(getStyle(obj, attr));
          let newvalue = oldvalue + speed;

          //向左移动时,需要判断newValue是否小于target speed是负数就要向左移动
          //向右移动时,需要判断newValue是否大于target speed是正数就要向有移动
          if (
            (speed < 0 && newvalue < target) ||
            (speed > 0 && newvalue > target)
          ) {
            newvalue = target;
          }
          obj.style[attr] = newvalue + "px";

          if (newvalue == target) {
            clearInterval(obj.timer);
            callback && callback();
          }
        }, 30);
      }
      /* 定义一个变量,用来保存定时器的标识
       * 目前我们的定时器的标识由全局变量timer保存,
      * 所有的执行正在执行的定时器都在这个变量中保存
       */
      let timer = null;
    </script>
  </body>
</html>
  • 写回答

3条回答 默认 最新

  • 拾梦逅 2022-08-03 11:22
    关注

    报错了吗?可以参考一下这个

    <html>
    
        <head>
            <title></title>
            <style type="text/css">
                * {
                    margin: 0;
                    padding: 0;
                }
                
                a {
                    text-decoration: none;
                }
                
                ul li {
                    list-style-type: none;
                }
                
                ol li {
                    list-style-type: none;
                }
                
                .wrap {
                    overflow: hidden;
                    position: relative;
                    margin: 100px auto;
                    width: 500px;
                    height: 400px;
                    background-color: pink;
                }
                
                .wrap ul {
                    position: absolute;
                    top: 0;
                    left: 0;
                    width: 500%;
                    /* 给ul盒子大一点就可以让li浮动起来 */
                }
                
                .wrap ul li {
                    float: left;
                    /* margin-right: 10px; */
                    width: 500px;
                    height: 400px;
                }
                
                .wrap ul li img {
                    width: 100%;
                    height: 100%;
                }
                
                .arrow-l,
                .arrow-r {
                    display: none;
                    position: absolute;
                    top: 38%;
                    text-align: center;
                    width: 24px;
                    height: 40px;
                    line-height: 40px;
                    color: white;
                    z-index: 999;
                    background: rgba(0, 0, 0, .3);
                }
                
                .arrow-r {
                    position: absolute;
                    top: 38%;
                    right: 0px;
                }
                
                .circle {
                    position: absolute;
                    bottom: 0;
                    left: 39%;
                    height: 20px;
                    width: 200px;
                    /* background-color: skyblue; */
                }
                
                .circle li {
                    float: left;
                    width: 20px;
                    height: 20px;
                    border-radius: 50%;
                    margin-right: 6px;
                    background: rgba(0, 0, 0, .3);
                }
                
                .circle .current {
                    background-color: #fff;
                }
            </style>
        </head>
    
        <body>
            <div class="wrap">
                <!-- 左右箭头按钮 -->
                <a href="javascript:;" class='arrow-l'>&lt</a>
                <a href="javascript:;" class='arrow-r'>&gt</a>
                <!-- 图片用li来装--核心滚动区域 -->
                <ul class='focus'>
                    <li>
                        <a href="#"><img src="1.jpg" alt=""></a>
                    </li>
                    <li>
                        <a href="#"><img src="2.jpg" alt=""></a>
                    </li>
                    <li>
                        <a href="#"><img src="3.jpg" alt=""></a>
                    </li>
                    <li>
                        <a href="#"><img src="4.jpg" alt=""></a>
                    </li>
    
                </ul>
                <!-- 底部小点点 -->
                <ol class='circle'>
    
                </ol>
            </div>
            <script type="text/javascript">
                window.addEventListener('load', function() {
                    // 1.
                    var arrowl = document.querySelector('.arrow-l');
                    var arrowr = document.querySelector('.arrow-r');
                    var focus = document.querySelector('.focus');
                    // 2.
                    // 效果1.鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮。
                    focus.addEventListener('mouseenter', function() {
                        arrowl.style.display = 'block';
                        arrowr.style.display = 'block';
                        clearInterval(timer);
                        timer = null; //清除定时器变量
                    })
                    focus.addEventListener('mouseleave', function() {
                        arrowl.style.display = 'none';
                        arrowr.style.display = 'none';
                        timer = setInterval(function() {
                            // 手动调用点击事件
                            arrowr.click();
                        }, 2000);
                    })
                    // 3.底部的小圆圈根据有几张图就有几个小圆圈来实行
                    var ul = document.querySelector('.focus');
                    var lis = focus.querySelectorAll('li');
                    var circle = document.querySelector('.circle');
                    var li = focus.querySelector('li');
                    var liWidth = li.offsetWidth;
                    // console.log(lis);只能得到4个节点
                    //console.log(focus.children.length); //这样才能得到focus的孩子的长度有几个
                    // 先对图片进行循环得到有几张图片
                    for(var i = 0; i < lis.length; i++) { //第一个for循环是创建li
                        var li = document.createElement('li');
    
                        // 记录小圆圈的索引号,通过自定义属性来做
                        li.setAttribute('index', i);
    
                        // 把上面增加的li添加到ol中去
                        circle.appendChild(li);
                        li.addEventListener('click', function() {
                            for(var i = 0; i < circle.children.length; i++) {
                                //创建的ol中的li进行遍历获取
                                // 排他思想
                                circle.children[i].className = '';
                            }
                            this.className = 'current'; //一定写成this
    
                            // 想要效果:点击小圆点,移动图片 移动的是ul
                            // 别移动的距离=小圆圈的索引号*图片的宽度(注意是负值从右往左走)
                            // 当我们点击某个小li就获取到li的索引号
                            var index = this.getAttribute('index');
                            var li = focus.querySelector('li');
                            // 解决bug1:当我们点击了某个li就拿到当前li的索引号给num
                            // 解决bug2:当我们点击了某个li 就把li的索引号给yuan
                            num = index;
                            yuan = index;
                            var liWidth = li.offsetWidth;
                            animate(ul, -liWidth * index); //ul移动
                        })
    
                    }
                    //把第一个li的背景变为白色
                    circle.children[0].className = 'current';
    
                    // 克隆第一张图片li放到ul最后
                    var first = ul.children[0].cloneNode(true);
                    ul.appendChild(first);
    
                    // 当点击左右按钮可以有轮播图切换效果
                    var num = 0;
                    // 效果:底部小圆圈跟随右侧按钮一起变化 设置一个全局变量计数(在点击事件外面定义)
                    var yuan = 0;
                    // flag节流阀
                    var flag = true;
    
                    // 右侧按钮
                    arrowr.addEventListener('click', function() {
                        if(flag) {
                            // flag = false; //关闭节流阀
                            // alert('111');测试 事件绑定成功没有
                            if(num == ul.children.length - 1) {
                                ul.style.left = 0;
                                num = 0; //无缝滚动效果 最后num=0回到起点第一张图
                            }
                            num++;
                            //          animate(ul, -num * liWidth, function() {
                            //              flag = true; //打开节流阀
                            //          });
                            //  效果:底部小圆圈跟随右侧按钮一起变化
                            yuan++; //这个变量是控制小圆圈的播放
                            // 如果yuan==4说明走到最后我们克隆的这张图片 我们就复原
                            if(yuan == circle.children.length) {
                                yuan = 0;
                            }
                            // 先清除其余小圆圈的current类名
                            for(var i = 0; i < circle.children.length; i++) {
                                circle.children[i].className = '';
                            }
                            circle.children[yuan].className = 'current';
                        }
                    })
    
                    // 左侧按钮
                    arrowl.addEventListener('click', function() {
                        if(flag) {
                            // flag = false;
                            // alert('111');测试 事件绑定成功没有
                            if(num == ul.children.length - 1) {
                                num = ul.children.length - 1;
                                //无缝滚动效果 最后num=0回到起点第一张图
                                ul.style.left = num * liWidth + 'px';
                            }
                            num--;
                            animate(ul, -num * liWidth, function() {
                                flag = true;
                            });
                            //  效果:底部小圆圈跟随右侧按钮一起变化
                            yuan--; //这个变量是控制小圆圈的播放
                            // 如果yuan<0说明第一张图片,则小圆圈要改为第四个小圆圈(3)
                            if(yuan < 0) {
                                yuan = circle.children.length - 1;
                            }
                            // 先清除其余小圆圈的current类名
                            for(var i = 0; i < circle.children.length; i++) {
                                circle.children[i].className = '';
                            }
                            circle.children[yuan].className = 'current';
                        }
    
                    })
                    // 自动播放轮播图
                    var timer = setInterval(function() {
                        // 手动调用点击事件
                        arrowr.click();
                    }, 2000);
    
                    /*
                         动画函数:
                             dom:要运动的节点对象
                             o:{属性:目标值,属性:目标值....}  (透明度使用属性:opacity:100) 透明度的值是0-100;  里面的opacity 和  filter会自动做转换。
                             time:切换的频率,表示运动的快慢
                             fn:回调函数,在运动执行完毕后执行。
                     */
                    function animate(dom, o, time, fn) {
                        if(time == undefined) { //默认的切换频率
                            time = 10;
                        }
                        //dom.termId :为每一个运动的物体添加一个属于自己的线程标识
                        clearInterval(dom.termId);
    
                        dom.termId = setInterval(function() { //创建一个定时器,实现运动
                            dom.isOver = true; //是否可以停止定時器
                            for(var property in o) {
                                if(property == "opacity") { //如果是透明度
                                    var currentValue = parseInt(getStylePropertyValue(dom, property) * 100); //当前样式属性的值        
                                } else { //其他样式属性
                                    var currentValue = parseInt(getStylePropertyValue(dom, property));
                                }
    
                                //速度   正速度  负速度
                                var speed = (o[property] - currentValue) / 10;
                                // 三元表达式  三目运算符
                                speed = currentValue > o[property] ? Math.floor(speed) : Math.ceil(speed)
    
                                currentValue += speed; //改变样式属性的值
    
                                if(currentValue != o[property]) {
                                    dom.isOver = false; //標識不停止定時器
                                }
    
                                if(property == "opacity") {
                                    dom.style.opacity = currentValue / 100;
                                    dom.style.filter = 'alpha(opacity= ' + currentValue + ')';
                                } else {
                                    dom.style[property] = currentValue + "px"; //改变物体的样式属性值        
                                }
    
                            }
    
                            if(dom.isOver) { //停止定时器
                                clearInterval(dom.termId);
                                if(fn) { //执行回调函数
                                    fn();
                                }
                            }
    
                        }, time) //基于切换的频率来改变运动的快慢
    
                    }
    
                    /*获取指定样式的属性值*/
                    function getStylePropertyValue(dom, property) {
                        if(window.getComputedStyle) { //標準瀏覽器
                            //
                            return getComputedStyle(dom, null)[property]; zzzzzzzzl
                        } else {
                            return dom.currentStyle[property]; //IE瀏覽器
                        }
                    }
                })
            </script>
        </body>
    
    </html>
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 9月30日
  • 已采纳回答 9月30日
  • 修改了问题 8月3日
  • 创建了问题 8月3日

悬赏问题

  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥15 键盘指令混乱情况下的启动盘系统重装
  • ¥40 复杂的限制性的商函数处理