目录
- HTML搭建
- 功能实现
- 小圆圈事件
- 左右按钮事件
- 自动播放
轮播图也叫焦点图,是网页中比较常见的网页特效。
功能:
- 鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮。
- 点击右侧按钮一次,图片往左播放一张,以此类推, 左侧按钮同理。
- 图片播放的同时,下面小圆圈模块跟随一起变化。
- 点击小圆圈,可以播放相应图片。
- 鼠标不经过轮播图, 轮播图也会自动播放图片。
- 鼠标经过,轮播图模块, 自动播放停止。
HTML搭建
分为三部分:1.左右按钮 2.图片 3.小圆圈
index.html
<!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>网页轮播图</title>
<link rel="stylesheet" href="./css/index.css">
<script src="./js/animate.js"></script>
<script src="./js/index.js"></script>
</head>
<body>
<div class="main">
<!-- 左右按钮 -->
<a href="javascript:;" class="left"><</a>
<a href="javascript:;" class="right">></a>
<!-- 图片 -->
<ul>
<li><img src="./img/scenery1.jpg" alt=""></li>
<li><img src="./img/scenery2.jpg" alt=""></li>
<li><img src="./img/scenery3.jpg" alt=""></li>
<li><img src="./img/scenery4.jpg" alt=""></li>
</ul>
<!-- 小圆圈 -->
<ol class="circle">
<li class="current"></li>
<li></li>
<li></li>
<li></li>
</ol>
</div>
</body>
</html>
index.css
*{
padding: 0;
margin: 0;
}
ul,ol{
list-style: none;
}
a{
text-decoration: none;
}
img {
width: 700px;
height: 400px;
}
.main{
position: relative;
width: 700px;
height: 400px;
margin: 100px auto;
background-color: pink;
}
/* 左右按钮 */
.left,
.right {
position: absolute;
top: 50%;
transform: translate(0, -50%);
width: 24px;
height: 40px;
background: rgba(0, 0, 0, .3);
text-align: center;
line-height: 40px;
color: #fff;
}
.right {
right: 0;
}
/* 图片 */
.main ul {
width: 1000%;
}
.main ul li{
float:left;
}
/* 小圆点 */
.circle {
position: absolute;
bottom: 20px;
left: 50%;
transform: translate(-50%, 0);
}
.circle li {
float: left;
width: 8px;
height: 8px;
border: 2px solid skyblue;
margin-left: 3px;
border-radius: 50%;
cursor: pointer;
}
.current {
background-color: skyblue;
}
效果
功能实现
小圆圈事件
因为小圆圈和图片的数量应该是一样的,如果小圆数量和图片的li数量是分开写,如果后期增减图片修改代码时比较麻烦,所以我们可以优化小圆代码,实现小圆数量随图片li数量一致。
方法:先清空ol里面的li
,先得到有多少张图片,然后用js
动态创建li
,再插入到ol
当中,实现自动化的效果,与此同时实现选中li,类名变为current
的功能
index.js
// 主体
var main = document.querySelector('.main');
// 1.小圆圈
// 动态生成圆圈
var ul = main.querySelector('ul');
var ol = main.querySelector('.circle');
for (var i = 0; i < ul.children.length; i++) {
var li = document.createElement('li');
//插入ol
ol.appendChild(li);
li.addEventListener('click', function() {
//所有li清除类名
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
//当前li设置current类名
this.className = 'current';
})
}
// 第一个小li设置为current
ol.children[0].className = 'current';
实现点击小圆图片滑动的效果,用到封装的动画函数animate.js
animate.js
function animate(obj, target, callback) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
clearInterval(obj.timer);
if (callback) {
callback();
}
}
obj.style.left = obj.offsetLeft + step + 'px';
}, 15);
}
核心算法:点击某个小圆,让图片滚动小圆的索引号乘以图片的宽度作为ul移动距离(因为图片是向左走,所以为负值),这里索引号需要创建自定义属性来获取。
注意:因为移动的是ul整个图片集合,所以ul需要定位才能使用animate
函数,不然没效果;给ul设置定位后左右按钮消失了,所以要给左右按钮再设置定位层级。
/* 图片 */
.main ul {
position: absolute;
left: 0;
top: 0;
width: 1000%;
}
index.js
for (var i = 0; i < ul.children.length; i++) {
var li = document.createElement('li');
//插入ol
ol.appendChild(li);
// 创建自定义属性
li.setAttribute('index', i);
li.addEventListener('click', function() {
//所有li清除类名
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
//当前li设置current类名
this.className = 'current';
var index = this.getAttribute('index');
var mainWidth = main.offsetWidth;
animate(ul, - index * mainWidth);
})
}
效果
左右按钮事件
原理与小圆圈的相似,给左右按钮添加事件,定义一个num
变量,每次点击自增1,ul移动的距离为 图片的宽乘于num
。
此外还要设置无缝滚动,不然图片会一直滚动下去。
无缝滚动:把ul的第一个li
克隆一份放到ul
的后面,当图片滚动到克隆的第一个图片时,让ul快速跳到左侧(即两个瞬间同步),left
为0,同时num
赋值为0。
克隆:使用代码实现,自动克隆
最后给main加上overhidden
index.js
// 切换图片
var first = ul.children[0].cloneNode(true);
ul.appendChild(first);
var num = 0;
right.addEventListener('click', function() {
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
animate(ul, - num * mainWidth);
})
效果
实现左右按钮与小圆圈切换同步
单独设置一个变量circle控制小圆的变化,点击右侧按钮就自加,到克隆的第一张图调回0。
index.js
// 小圆圈变化
var circle = 0;
right.addEventListener('click', function() {
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
animate(ul, - num * mainWidth);
circle++;
if (circle == ol.children.length) {
circle = 0;
}
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[circle].className = 'current';
})
但是此时有个问题:
点击了小圆圈再点击右按钮图片滚动时,图片的实际位置发生错乱,图片的位置不对应。
这是因为右侧按钮点击事件时通过变量num
来控制的,而num
变量和小圆圈的点击事件没有任何关系,而发生错乱。
解决:
把num
和circle
的值改为点击li的索引号的值,这一步是在创建li时加的
var index = this.getAttribute('index');
circle = num = index;
左按钮与右按钮类似,反过来即可
left.addEventListener('click', function() {
if (num == 0) {
num = ul.children.length - 1;
ul.style.left = - num * mainWidth + 'px';
}
num--;
animate(ul, - num * mainWidth);
circle--;
if (circle < 0) {
circle = ol.children.length - 1;
}
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[circle].className = 'current';
})
自动播放
添加定时器,把点击事件 right.click()放在定时器中即可,相当于自动点击右按钮播放
// 3.自动播放
var timer = this.setInterval(function() {
right.click();
}, 2000)
效果