案例:网页轮播图

z案例:网页轮播图
也称为焦点图

功能需求:
鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮
点击右侧按钮一次,图片往左播放一次,依此类推,左按钮同理
图片播放的同时,下面小圆圈模块跟随一起变化
点击小圆圈,可以播放相应图片
鼠标不经过轮播图,轮播图也会自动播放
鼠标经过轮播图模块,自动播放停止
其中模块:
动态生成小圆圈:
核心思路:小圆圈的个数要和图片张数一致
首先得到ul里面图片的数量,(图片放入li里面,所以是li的个数)
利用循环动态生成小圆圈(这个小圆圈要放入ol里面)
创建节点 createElement (’ li ')
插入节点 ol.appendChild ( li )
第一个小圆圈添加类名li.children[0].className = "current";
点击小圆圈,可以播放相应图片
排他思想: 点击当前小圆圈,就添加current 类,其余的就移除这个类

点击小圆圈滚动图片
此时用到 animate 动画函数,将js文件引入,因为index.js 依赖 animate.js 所以 animate.js 必须写到 index.js 上面
使用动画函数的前提,该元素必须有定位
是ul 移动 ,不是 li
滚动图片核心算法:点击某个小圆圈,就让图片滚动小圆圈的索引号乘以图片的宽度(是负值)作为 ul 的移动距离
此时需要知道小圆圈的索引号,我们可以在生成小圆圈的时候给他设置一个自定义属性,点击的时候获取这个自定义属性即可
点击右侧按钮一次,图片往左播放一次
声明一个变量 num 点击一次 自增一 ,让这个变量乘以图片宽度,就是ul的滚动距离
图片滚动到最后一张时,用到图片无缝滚动
图片无缝滚动原理:把ul 的第一个 li 复制一份,放到 ul 的最后面
当图片滚动到最后一张时,让ul快速的,不做动画地跳到最左侧:left 为 0
同时把 num 赋值为 0 ,重新开始滚动
克隆第一张图片
克隆ul 第一个 li cloneNode() 加 true 深克隆 复制里面的子节点 false 浅克隆
添加到ul 最后面appendChild
-图片播放的同时,下面小圆圈模块跟随一起变化

最简单的做法是再声明一个变量circle ,每次点击自增一,注意:左侧按钮也需要这个变量,因此声明全局变量
因为前面把第一张图片克隆了,因此小圆圈比图片少一个,要加一个判断条件:if circle = 图片数量-1 说明走到了克隆的图片了 此时让circle = 0 复原回去
自动播放
添加一个定时器
自动播放轮播图,实际就类似于点击了右按钮
此时我们使用手动调用右侧按钮点击事件 arrow_r.click()
鼠标经过focus 就停止定时器
节流阀
用于防止轮播图连续点击造成播放过快

节流阀目的:当上一个函数动画执行完毕,再去执行下一个函数动画,让事件无法连续触发

核心思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数

开始设置一个变量 var flag = true;
if (flag){flag=flase;do something;} 关闭水龙头
利用回调函数,动画执行完毕,flag = true 打开水龙头
(os:但是我下面的代码不知道为什么实现不了节流阀功能,就没加进去,如果有大佬看到了知道怎么改请指教一下)
如果加上节流阀,布局应该是下面的样式:
 

 var flag = true; //节流阀
  arrow_r.addEventListener("click", function () {
    if (flag) {
      flag = false;
      //如果走到了最后复制的一张 ul 要快速复原 left 改为0
     .........
      animate(ul, -num * focusWidth, function () {
        flag = true; //打开节流阀
      });
    .........
    }
  });
 arrow_l.addEventListener("click", function () {
    if (flag) {
      flag = false;
      //如果走到了最后复制的一张 ul 要快速复原 left 改为0
     ...........
      animate(ul, -(num * focusWidth), function () {
        flag = true;
      });
    ...........
    }
  });

代码:
HTML 代码:

   <!-- 引入首页的css文件 -->
   <link rel="stylesheet" href="css/index.css" />
   <!-- 引入JS文件 -->
   <script src="js/animate.js"></script>
   <!--这个JS文件必须写到 index.js 上面-->
   <script src="js/index.js"></script>
  </head>

  <body>
     <div class="focus fl">
          <!-- 左侧按钮 -->
          <a href="javascript:;" class="arrow_l"> &lt; </a>
          <!-- 右侧按钮 -->
          <a href="javascript:;" class="arrow_r"> &gt; </a>
          <!-- 必须用ul布局 轮播图效果核心的滚动区域 -->
          <!-- 有几个li 轮播图内就有几个图片 -->
          <ul>
            <li>
              <a href="#"><img src="upload/focus1.jpg" /></a>
            </li>
            <li>
              <a href="#"><img src="upload/focus2.jpg" /></a>
            </li>
            <li>
              <a href="#"><img src="upload/focus3.jpg" /></a>
            </li>
            <li>
              <a href="#"><img src="upload/focus4.jpg" /></a>
            </li>
          </ul>
          <!-- 小圆圈 -->
          <ol class="circle"></ol>
   </div> 

CSS代码:

.fl {
    float: left;
} 
.focus {
  position: relative;
  height: 440px;
  width: 721px;
  background-color: purple;
  overflow: hidden;
}
.focus ul {
  position: absolute; /*加上定位才可以使用动画*/
  top: 0;
  left: 0;
  width: 600%; /*设为父盒子宽度的600% 确保轮播图的四个图片有足够宽的位置浮动起来*/
}
.focus ul img {
  width: 720px;
  height: 440px;
  float: left;
}
.arrow_l,
.arrow_r {
  display: none; /*为了轮播图效果先隐藏按钮*/
  position: absolute;
  top: 50%; /* 走父亲高度的一半 */
  transform: translateY(-50%); /* 走的自己高度的一半 */
  width: 24px;
  height: 40px;
  background: rgba(0, 0, 0, 0.3);
  font-family: "icomoon";
  font-size: 18px;
  text-align: center;
  line-height: 40px;
  color: #fff;
  z-index: 2; /*添加层级,让它在ul里面显示出来*/
}
.arrow_r {
  right: 0;
}
.circle {
  position: absolute;
  bottom: 10px;
  left: 50px;
}
.circle li {
  float: left;
  width: 8px;
  height: 8px;
  /* background-color: #fff; */
  border: 2px solid rgba(255, 255, 255, 0.5);
  margin: 0 3px;
  border-radius: 50%;
  /* 鼠标经过显示小手 */
  cursor: pointer;
}
.current {
  background-color: #fff;
}

JS 代码:

window.addEventListener("load", function () {
  //预加载
  //1.获取元素
  var arrow_l = document.querySelector(".arrow_l");
  var arrow_r = document.querySelector(".arrow_r");
  var focus = document.querySelector(".focus");
  var focusWidth = focus.offsetWidth; //获取图片宽度

  //2.鼠标经过轮播图区域 左右按钮显示
  focus.addEventListener("mouseenter", function () {
    arrow_l.style.display = "block";
    arrow_r.style.display = "block";
    //停止定时器,停止自动播放
    clearInterval(timer);
    timer = null; //清除定时器变量
  });

  //鼠标离开轮播图区域 左右按钮隐藏
  focus.addEventListener("mouseleave", function () {
    arrow_l.style.display = "none";
    arrow_r.style.display = "none";
    //开启定时器,自动播放开始
    timer = setInterval(function () {
      //手动调用点击事件
      arrow_r.click();
    }, 2000);
  });

  //3.动态生成小圆圈 里面有几张图片 就创建几个小圆点
  var ul = focus.querySelector("ul");
  var ol = focus.querySelector(".circle");
  for (var i = 0; i < ul.children.length; i++) {
    //创建一个li
    var li = document.createElement("li");
    //记录当前小圆圈的索引号 通过自定义属性来做
    li.setAttribute("index", i);
    //把li插入ol里面
    ol.appendChild(li);

    //4.小圆圈的排他事件 可以在生成小圆圈的同时直接绑定事件
    // 点击当前小圆圈,就添加current 类,其余的就移除这个类
    li.addEventListener("click", function () {
      //(1)干掉所有人 所有li 清除 current 类名
      for (var i = 0; i < ol.children.length; i++) {
        ol.children[i].className = "";
      }
      //(2)留下自己 自己添加 current 类名
      this.className = "current";

      //5.点击小圆圈,移动图片 移动的是ul
      //ul移动距离:小圆圈的索引号乘以图片的宽度(是负值)
      //点击了小圆圈,就拿到当前li的索引号
      var index = this.getAttribute("index");
      //当点击了某个li 就把这个li的索引号给 num
      num = index;
      //当点击了某个li 就把这个li的索引号给 circle
      circle = index;
      animate(ul, -(index * focusWidth));
    });
  }

  //第一个ol小圆圈添加类名 current
  ol.children[0].className = "current";
  //6.克隆第一张图片 放到最后面
  var first = ul.children[0].cloneNode(true);
  ul.appendChild(first);

  //7.点击右侧按钮,图片滚动一张
  var num = 0;
  var circle = 0; //控制小圆圈的播放
  //var flag = true; //节流阀
  arrow_r.addEventListener("click", function () {
    //如果走到了最后复制的一张 ul 要快速复原 left 改为0
    if (num == ul.children.length - 1) {
      ul.style.left = 0;
      num = 0;
    }
    num++;
    animate(ul, -num * focusWidth);
    //8.点击右侧按钮,小圆圈跟着一起变化,可以再声明一个变量控制小圆圈的播放
    //如果circle = 4 ,即走到最后了,复原
    circle++;
    if (circle == ol.children.length) {
      circle = 0;
    }
    circleChange(); //调用函数
  });

  //9.点击左侧按钮,图片滚动一张
  arrow_l.addEventListener("click", function () {
    //如果走到了最后复制的一张 ul 要快速复原 left 改为0
    if (num == 0) {
      num = ul.children.length - 1;
      ul.style.left = -num * focusWidth + "px";
    }
    num--;
    animate(ul, -(num * focusWidth));
    //点击左侧按钮,小圆圈跟着一起变化,可以再声明一个变量控制小圆圈的播放
    circle--;
    //如果 circle < 0 说明是第一张图片 此时小圆圈要改为第四个小圆圈(3)
    if (circle < 0) {
      circle = ol.children.length - 1;
    }
    circleChange(); //调用函数
  });

  function circleChange() {
    //先清除其余小圆圈类名
    for (var i = 0; i < ol.children.length; i++) {
      ol.children[i].className = "";
    }
    //留下当前小圆圈的 current 类名
    ol.children[circle].className = "current";
  }

  //10.自动播放功能
  var timer = setInterval(function () {
    //手动调用点击事件
    arrow_r.click();
  }, 2000);
});

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值