也称为焦点图
排他思想: 点击当前小圆圈,就添加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"> < </a> <!-- 右侧按钮 --> <a href="javascript:;" class="arrow_r"> > </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); });其中:所需JS文件的 animate.js 见另一篇文:动画函数的实现、封装、回调函数