美文网首页视觉艺术JavaScript前端
【前端案例】 19 - 案例:网页轮播图

【前端案例】 19 - 案例:网页轮播图

作者: itlu | 来源:发表于2020-12-18 11:22 被阅读0次

    案例演示

    轮播图

    功能需求:

    1. 鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮;

    2. 点击右侧按钮一次,图片往左播放一张,以此类推,左侧按钮同理;

    3. 图片播放的同时,下面小圆圈模块跟随一起变化;

    4. 点击小圆圈,可以播放相应图片;

    5. 鼠标不经过轮播图,轮播图也会自动播放图片;

    6. 鼠标经过,轮播图模块, 自动播放停止。

    代码实现

    css
    * {
      padding: 0;
      margin: 0;
    }
    
    a {
      text-decoration: none;
      color: #ccc;
    }
    
    ul,
    ol {
      list-style: none;
    }
    
    .focus {
      position: relative;
      width: 590px;
      /* 需要设置高度之后绝对子元素绝对定位才能使用百分比 */
      height: 470px;
      margin: 100px auto;
      overflow: hidden;
    }
    
    .focus li img {
      width: 100%;
    }
    
    .arrow-left,
    .arrow-right {
      display: none;
      position: absolute;
      top: 50%;
      width: 38px;
      height: 38px;
      line-height: 38px;
      text-align: center;
      color: #fff;
      font-weight: 700;
      cursor: pointer;
      background-color: rgba(0, 0, 0, .3);
      transform: translateY(-50%);
      transition: all 1s linear;
      z-index: 2;
    }
    
    .arrow-left:hover,
    .arrow-right:hover {
      color: #ccc;
    }
    
    .arrow-left {
      left: 0;
      border-radius: 0 15px 15px 0;
    }
    
    .arrow-right {
      right: 0;
      border-radius: 15px 0 0 15px;
    }
    
    .focus ul {
      position: absolute;
      top: 0;
      left: 0;
      width: 600%;
    }
    
    .focus ul li {
      float: left;
    }
    
    .focus ol {
      position: absolute;
      bottom: 16px;
      left: 50%;
      /*  移动自身宽度的50% */
      transform: translateX(-50%);
    }
    
    .focus ol li {
      float: left;
      margin-right: 10px;
      width: 5px;
      height: 5px;
      border-radius: 50%;
      cursor: pointer;
      border: 3px solid rgba(255, 255, 255, .5);
    }
    
    .focus ol li.cur_point {
      background-color: #fff;
      border-color: #ffffff;
    }
    
    
    html
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"
            ,maximum-scale=1.0,minimum-scale=1.0>
      <title>网页轮播图</title>
      <link rel="stylesheet" href="css/index.css">
      <link rel="stylesheet" href="css/iconfont.css">
      <script src="./js/animation.js"></script>
      <script src="./js/index.js"></script>
    </head>
    <body>
    
    <div class="focus">
      <!-- javascript:void(0); 阻止页面跳转 -->
      <a href="javascript:void(0);" class="arrow-left">
        <i class="iconfont icon-zuoyou"></i>
      </a>
      <a href="javascript:void(0);" class="arrow-right">
        <i class="iconfont icon-icon-you"></i>
      </a>
    
      <ul>
        <li><a href="javascript:void(0);"><img src="images/focus1.jpg.webp" alt=""></a></li>
        <li><a href="javascript:void(0);"><img src="images/focus4.jpg.webp" alt=""></a></li>
        <li><a href="javascript:void(0);"><img src="images/focus2.jpg.webp" alt=""></a></li>
        <li><a href="javascript:void(0);"><img src="images/focus3.jpg.webp" alt=""></a></li>
      </ul>
    
      <ol></ol>
    </div>
    
    </body>
    </html>
    
    javascript
    /**
     * 绑定页面加载完成之后再指定js的事件
     */
    window.addEventListener('load', () => {
      // 获取元素
      let focus = document.querySelector('.focus');
      let ul = focus.querySelector('ul');
      let arrowRight = focus.querySelector('.arrow-right');
      let arrowLeft = focus.querySelector('.arrow-left');
      let focusWidth = focus.offsetWidth;
      let lisSize = ul.children.length;
      let ol = focus.querySelector('ol');
      let time = 1000;
    
    
      /**
       * 当鼠标接触到轮播图的时候显示左右切换按钮
       */
      focus.addEventListener('mouseenter', () => {
        arrowRight.style.display = 'block';
        arrowLeft.style.display = 'block';
        // 当鼠标进入时清除定时器
        clearInterval(timer);
        timer = null;
      })
    
    
      /**
       * 当鼠标离开轮播图的时候隐藏左右切换按钮
       */
      focus.addEventListener('mouseleave', () => {
        arrowRight.style.display = 'none';
        arrowLeft.style.display = 'none';
        /**
         * 当鼠标离开的时候重新设置定时器
         * @type {number}
         */
        timer = setInterval(() => {
          arrowRight.click();
        }, time);
      })
    
    
      /**
       * 根据ul中 li 的个数创建 ol中li的个数小圆点
       */
      for (let i = 0; i < lisSize; i++) {
        // 创建一个节点
        let li = document.createElement('li');
        // 为每一个 li 设置自定义属性
        li.setAttribute('data-index', i + '');
        // 追加节点
        ol.appendChild(li);
    
        /**
         * 为每一个小圆点注册点击事件选中时,出现未选中状态
         */
        ol.children[i].addEventListener('click', () => {
          for (let i = 0; i < ol.children.length; i++) {
            ol.children[i].className = '';
          }
          ol.children[i].className = 'cur_point';
          // 获取自定义属性
          let dataIndex = ol.children[i].getAttribute('data-index');
          // 调用动画进行切换
          animation(ul, -dataIndex * focusWidth)
          // 将 num 赋值为当前自定义属性
          num = dataIndex;
          circle = dataIndex;
        })
      }
    
      // 在这里设置因为上面刚创建了 li 添加到 ol 中
      ol.children[0].className = 'cur_point';
    
      // 将子第一个节点深拷贝到最后
      let firstLi = ul.children[0].cloneNode(true);
      // 将该节点添加到ul的后面
      ul.appendChild(firstLi);
    
      let circle = 0;
      let num = 0;
      // 节流阀: 利用回调函数原理需要执行完上一件事之后再执行下一件事
      let flag = true;
      /**
       * 向右切换图片
       */
      arrowRight.addEventListener('click', (e) => {
        if (flag) {
          // 关闭水龙头
          flag = false;
          if (num >= lisSize) {
            num = 0;
            ul.style.left = 0 + 'px';
          }
          num++;
          animation(ul, -(num * focusWidth), () => {
            // 执行回调函数 打开水龙头
            flag = true;
          });
          circle++;
          if (circle >= lisSize) {
            circle = 0
          }
          curPoint(circle);
        }
      })
    
    
      /**
       * 向左切换图片
       */
      arrowLeft.addEventListener('click', () => {
        if (flag) {
          flag = false;
          if (num <= 0) {
            num = lisSize;
            // 当前 ul 距离左侧的距离是
            ul.style.left = -(num * focusWidth) + 'px';
          }
          num--;
          animation(ul, -(num * focusWidth), () => {
            flag = true;
          });
          circle--;
          if (circle < 0) {
            circle = lisSize - 1;
          }
          curPoint(circle);
        }
      })
    
    
      /**
       * 将当前点设置为选中状态
       * @param index
       */
      function curPoint(index) {
        for (let i = 0; i < ol.children.length; i++) {
          ol.children[i].className = '';
          ol.children[index].className = 'cur_point';
        }
      }
    
      /**
       * 向右切换的 调用默认点击
       * @type {number}
       */
      let timer = setInterval(() => {
        arrowRight.click();
      }, time)
    
    })
    
    animation.js 实现切换图片动画,实现了一个缓动动画
    function animation(obj,target,callback) {
      clearInterval(obj.timer);
      obj.timer = setInterval(()=> {
        // 计算步长
        let step = (target - obj.offsetLeft) / 10;
        // 判断当前的步长是否大于 0 大于0 则向上取整,反之向下取整
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        // 设置 元素对象的 left 属性使盒子移动
        obj.style.left = obj.offsetLeft + step + 'px';
        // 判断移动的距离是否查出目标值 如果超出则将定时器移除
        if (obj.offsetLeft === target) {
          clearInterval(obj.timer);
          callback && callback(); // 相当于 if(callback) {callback()}
          // 动画执行完成之后再执行回调函数
        }
      },15)
    }
    

    相关文章

      网友评论

        本文标题:【前端案例】 19 - 案例:网页轮播图

        本文链接:https://www.haomeiwen.com/subject/wdzagktx.html