八、轮播图案例
8.1轮播图-静态页面
轮播图又称焦点图,是网页中较为常见的网页特效。
- 页面布局:
- 静态页面实现:
①编写静态页面后,要让图片浮动,置于同一行。
②若出现图片未一行的情况,是ul不够长,导致未能装下其中li的一个个小图片,只需将ul的宽度设置为400%,即外围大盒子的4倍即可。
html代码
<div class="focus"> <!-- 左侧按钮箭头 --> <a href="#" class="prev"> < </a> <!-- 右侧按钮箭头 --> <a href="#" class="next"> > </a> <!-- 滚动图片区域 --> <ul class="focus"> <li> <a><img src="./img/01.png" alt=""></a> </li> <li> <a><img src="./img/02.png" alt=""></a> </li> <li> <a><img src="./img/03.png" alt=""></a> </li> <li> <a><img src="./img/03.png" alt=""></a> </li> </ul> <!-- 小圆点 --> <ul class="circle"> <li class="current"></li> <li></li> <li></li> <li></li> <li></li> </ul> </div>
css代码:
<style> * { margin: 0; padding: 0; } li { list-style: none; } .focus { position: relative; width: 520px; height: 280px; background-color: pink; margin: 100px auto; } .focus ul{ /* 设置ul宽度为focus的4倍,使其可以装下多个浮动的li */ width: 400%; } .focus img { width: 520px; height: 280px; } /* 并集选择器可以集体声明相同的样式 */ .prev, .next { position: absolute; /* 绝对定位的盒子垂直居中 */ top: 50%; margin-top: -15px; /* 加了绝对定位的盒子可以直接设置高度和宽度 */ width: 20px; height: 30px; background: rgba(0, 0, 0, .3); text-align: center; line-height: 30px; color: #fff; text-decoration: none; } .prev { left: 0; /* border-radius: 15px; */ border-top-right-radius: 15px; border-bottom-right-radius: 15px; } .next { /* 如果一个盒子既有left属性也有right属性,则默认会执行 left属性 同理 top bottom 会执行 top */ right: 0; /* border-radius: 15px; */ border-top-left-radius: 15px; border-bottom-left-radius: 15px; } .focus ul li{ float: left; } .circle { position: absolute; bottom: 15px; left: 50%; margin-left: -35px; width: 70px; height: 13px; /* background-color: pink; */ background: rgba(255,255,255, .3); border-radius: 7px; } .circle li { float: left; width: 8px; height: 8px; background-color: #fff; border-radius: 50%; margin: 3px; } /* 不要忘记选择器权重的问题 */ .circle .current { background-color: #ff5000; } </style>
8.2轮播图-js动态页面
(1)功能点:
①鼠标经过轮播图区域,出现← →
鼠标离开轮播图区域,隐藏← →
-
先将↔按钮设为不可见
-
利用mosouenter和mouseleave绑定鼠标事件即可
②点击左右按钮,图片可切换
③播放图片时,底部小圆圈相应变化选中状态
④点击小圆圈,可切换对应轮播图片
⑤鼠标离开,轮播图会自动播放
鼠标点击,轮播图会停止自动播放
(2)要求:
此时js代码较多,因单独新建js文件,引入页面中
添加load事件,防止页面元素未加载完全找不到元素
1️⃣左右箭头出现
利用mouseenter和mouseleave两事件
实现鼠标经过箭头显示,鼠标离开箭头消失
2️⃣动态生成小圆圈
圆圈个数和图片数一致
先得到ul中图片张数(即li的个数)
利用循环动态生成小圆圈(放入ol中)
- 创建节点 createElement('li')
- 插入节点 ol.appendChild('li')
- 绑定点击事件+排他思想
- 可以创建节点的同时绑定事件哦!!
第一个小圆圈默认添加current类
- 默认轮播开始的第一张
3️⃣引入动画js文件+添加定位
将动画函数写入单独js文件,引入js文件
- 当其他js文件,需要使用动画函数js时,要将动画函数js放在其上方。
为移动区域ul,添加absolute绝对定位
-
注意是ul在移动,而非li
-
因为动画函数的使用,要求元素必须有定位
3️⃣实现点击圆圈图片滚动
滚动的核心算法:小圆圈索引号*图片的宽度=ul的移动距离
创建节点后,定义小圆圈的自定义属性
-
定义自定义data-index属性
-
使用setAttribute('属性名',属性值)
- 属性名 data-index
- 属性值 循环变量---i
在小圆圈的点击事件中,计算ul移动距离+调用动画函数
-
offsetWidth得到图片宽度
-
getAttribute得到圆圈下标属性
-
❗:在事件函数中,最好用this
-
否则取下标的时候出不来
-
-
求ul移动距离:当前点击圆圈下标值*图片宽度
最后,调用动画函数。
4️⃣图片随着右侧按钮变化
先将ul的第一个li克隆,追加到ul最后
- 克隆:element.clone(true);true表示深克隆,复制其中子节点
- 追加:append(节点)
声明一个变量num,绑定点击事件
- 声明 num =0;
每次点击,判断是否是最后一张
- 是--》回到第一张
- ul的left值为0,同时num清0
- 否--》num++,调用动画函数
- 调用:animate(移动对象,移动距离)
- 移动距离:第几张图*图片宽度
- 调用:animate(移动对象,移动距离)
当滚到最后一张时,让ul快速回到最左侧:left为0
同时重新赋值num=0
5️⃣小圆圈随右侧按钮变化
声明一个circle变量,每次点击右侧按钮时+1【注意声明全局变量】
判断circle是否等于ol中的children
- 是,circle为0
- 否,设置小圆圈为选中状态【排他思想】
❗:点击小圆圈到第三张图,点击下一张,小圆圈不匹配
- 得到小圆圈索引值时,要将其赋给num和circle
6️⃣轮播图自动播放
先设置定时器setInterve
- 将定时器命名为timer,方便之后清除
自动播放:相当于手动调用右侧按钮点击事件
- element.click()相当于直接调用点击事件
鼠标经过focus,停止定时器
- 在鼠标
鼠标离开focus,开启定时器
动画函数js
// obj目标对象,target目标位置 // 给不同的元素指定不同的定时器 function animate(obj, targt, callback) { // 当我们不断地点击按钮,元素的速度越来越快,因为开启了太多定时器 // 解决方案,让元素只有一个定时器(清除上一个定时器,只保留当前的定时器) clearInterval(obj.timer); obj.timer = setInterval(function () { // 步长值 // 把步长值改为正直 ,向上取整 var step = (targt - obj.offsetLeft) / 10; step = step > 0 ? Math.ceil(step) : Math.floor(step); if (obj.offsetLeft == targt) { // 停止定时器 clearInterval(obj.timer); // if (callback) { // callback(); //回调函数 // } callback && callback(); } // 把每次+1这个步长值逐渐变小,步长公式 (目标位置值 - 现在的位置)/10 obj.style.left = obj.offsetLeft + step + 'px'; }, 15); }
轮播图js(基于动画函数js)
window.addEventListener('load',function(){ //1.获取元素 // ①左按钮,右按钮 var prev = this.document.querySelector('.prev'); var next = this.document.querySelector('.next'); // ②滑动区域 var focus = this.document.querySelector('.focus'); // ③小圆点 var ol = this.document.querySelector('.circle'); var ImgWidth = focus.offsetWidth;//图片宽度 // ④图片选中位置 var num = 0;//控制左右滑动 // ⑤小圆圈选中位置 var circle = 0;//控制小圆圈的播放 //2.鼠标经过再显示左右按钮 focus.addEventListener('mouseenter',function(){ prev.style.display = 'block'; next.style.display = 'block'; //停止定时器 clearInterval(timer); //将定时器置null timer = null; }) //3.鼠标离开隐藏左右按钮 focus.addEventListener('mouseleave',function(){ prev.style.display = 'none'; next.style.display = 'none'; //开启定时器,因为下方已经声明,所以只需要重新定义即可 timer = setInterval(function(){ //调用右侧点击事件 next.click(); },3000) }) //4.动态生成小圆圈:图有几个,○就有几个 var ul = focus.querySelector('ul'); //获取图片张数 ul的li数量 for(var i = 0;i < ul.children.length; i ++){ //依次循环,创建li节点 var li = document.createElement('li'); //设置自定义属性 li.setAttribute('data-index',i); //插入到ol中 ol.appendChild(li); //生成圆圈的同时绑定事件 li.addEventListener('click',function(){ //干掉所有人 for(var i = 0; i < ol.children.length; i++){ //清除他人的类 ol.children[i].className = ''; } //留下自己 this.className = 'current'; //5.点击小圆圈,放图片的ul对应移动 //得到图片宽度+自定义圆圈索引号 // var ImgWidth = focus.offsetWidth;//图片宽度 var index = this.getAttribute('data-index');//索引号 num = index; circle = index; console.log('看看当前的图片宽度'+ImgWidth); console.log('看看索引号'+index); //求ul移动的距离:小圆圈下标*图片宽度 var target = index*ImgWidth; //②调用动画函数 animate(ul,-target); }) } //默认设置第一个圆圈为选中 ol.children[0].className = 'current'; //6.克隆ul的第一个li,放到ul最后 var first = ul.children[0].cloneNode(true); ul.appendChild(first); /*!!!!!!!!!!!!!右侧按钮事件!!!!!!!!!!!!!!!!!*/ //7.点击右滑按钮,图片向右滚动一张 // var num = 0;//控制左右滑动 // var circle = 0;//控制小圆圈的播放 next.addEventListener('click',function(){ if(num == ul.children.length - 1 ){ ul.style.left = 0; num = 0; } num++; animate(ul,-num*ImgWidth); //让小圆圈随之变化 circle++; //保证滑到ol中克隆出来的最后一张图时,会跳转到第一张。 if(circle == ol.children.length){ circle = 0; } circleChange(); }) /*!!!!!!!!!点击左滑按钮,小圆圈随着一起变化!!!!!!!!!!!*/ //8.左滑按钮的点击事件 prev.addEventListener('click',function(){ //如果滑到第一张,就跳到最后一张图片去 if(num == 0 ){ //跳到最后一张:left=ol的最后一个下标*图片宽度 num = ol.children.length-1; ul.style.left = - num * ImgWidth + 'px'; } num--; animate(ul,-num*ImgWidth); //让小圆圈随之变化 circle--; //如果circle<0,说明小圆圈要跳到ol的最后一个 if(circle < 0 ){ circle = ol.children.length-1; } circleChange(); }) //10.自动播放轮播图的定时器 //在鼠标移动+鼠标离开时,添加相应步骤 var timer = this.setInterval(function(){ next.click(); },1000) //9.封装的圆圈选中变化函数 function circleChange(){ //清除其他小圆圈的current类名 for(var i = 0; i < ol.children.length;i++){ ol.children[i].className = ''; } //留下当前小圆圈的current类名 ol.children[circle].className = 'current'; } })
为防止轮播图切换过快,可以定义一个flag变量,初值为true
执行左/右点击事件后,当flag为true时,flag变为false,图片执行切换效果;而在动画函数的回调函数中,flag恢复为true。保证下一次切换效果。