css部分
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
.focus {
position: relative;
width: 730px;
height: 300px;
margin: 100px auto;
overflow: hidden;
}
.prev,
.next {
display: none;
position: absolute;
top: 50%;
margin-top: -15px;
/* 加了绝对定位的盒子可以直接设置高度和宽度 */
width: 20px;
height: 30px;
background-color: rgba(0, 0, 0, .3);
text-align: center;
line-height: 30px;
color: #fff;
text-decoration: none;
z-index: 2;
}
.prev {
left: 0;
border-top-right-radius: 15px;
border-bottom-right-radius: 15px;
}
.next {
right: 0;
border-top-left-radius: 15px;
border-bottom-left-radius: 15px;
}
.focus ul {
width: 600%;
position: absolute;
top: 0;
left: 0;
}
.focus ul li {
float: left;
}
.focus ol {
position: absolute;
left: 50%;
bottom: 15px;
}
.focus ol li {
float: left;
margin: 3px;
width: 8px;
height: 8px;
background-color: #fff;
border-radius: 4px;
}
.selected {
background-color: #ff500f !important;
}
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>Document</title>
<link rel="stylesheet" href="index.css">
<script src="js/animate.js"></script>
<script src="js/index.js"></script>
</head>
<body>
<div class="focus">
<!-- 左侧按钮 -->
<a href="javascript:;" class="prev"><</a>
<!-- 右侧按钮 -->
<a href="javascript:;" class="next">></a>
<ul>
<li><img src="image/focus1.jpg" alt=""></li>
<li><img src="image/focus2.jpg" alt=""></li>
<li><img src="image/focus3.jpg" alt=""></li>
<li><img src="image/focus4.jpg" alt=""></li>
</ul>
<!-- 小圆圈 -->
<ol></ol>
</div>
</body>
</html>
JS部分
window.addEventListener('load', function () {
var prev = document.querySelector('.prev');
var next = document.querySelector('.next');
// 1. 鼠标经过轮播图 左右按钮显示
document.addEventListener('mouseenter', function () {
prev.style.display = 'block';
next.style.display = 'block';
// 9. 鼠标经过轮播图,停止自动播放
clearInterval(timer);
timer = null;
})
// 2. 鼠标经过轮播图 左右按钮显示
document.addEventListener('mouseleave', function () {
prev.style.display = 'none';
next.style.display = 'none';
// 10. 鼠标离开轮播图,继续自动播放
timer = setInterval(function () { // 因为下面定义了 timer,这里不需重新声明 var
next.click();
}, 2000);
})
// 3. 动态生成小圆圈
var ul = document.querySelector('ul');
var ol = document.querySelector('ol');
var focus = document.querySelector('.focus');
var focusWidth = focus.offsetWidth;
for (var i = 0; i < ul.children.length; i++) {
var li = document.createElement('li');
// 为每隔小圆圈设置索引号
li.setAttribute('data-index', i);
// 点击小圆圈使得当前小圆圈变色
li.addEventListener('click', function () {
// 排它思想
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
this.className = 'selected';
// 4. 点击小圆圈滚动图片
var index = this.getAttribute('data-index');
// 7. 解决2个 bug (点了小圆点后再点按钮图像轮播顺序出错)
num = index;
circle = index;
animate(ul, -index * focusWidth);
});
ol.appendChild(li);
}
// 第一个小圆点初始时刻被选中
ol.children[0].className = 'selected'
// 为了实现无缝滚动 第一张图片复制一份,放在所有图片后面
var first = ul.children[0].cloneNode(true);
ul.append(first);
// 5. 点击右侧按钮图片滚动一次
var num = 0;
// 6. 为使小圆圈跟随按钮变化,设置全局变量 circle
var circle = 0;
var flag = true;
next.addEventListener('click', function () {
if (flag) {
flag = false; // 关闭节流阀
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
animate(ul, - num * focusWidth, function () {
flag = true; // 动画完成后打开节流阀
});
circle++;
if (circle == 4) {
circle = 0
}
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[circle].className = 'selected';
}
});
// 8. 自动播放轮播图
var timer = setInterval(function () {
next.click();
}, 2000);
// 11. 设置左侧按钮功能
prev.addEventListener('click', function () {
if (flag) {
flag = false;
if (num == 0) {
num = ul.children.length - 1;
ul.style.left = - num * focusWidth + 'px'; // 注意 px
}
num--;
animate(ul, - num * focusWidth, function() {
flag = true;
}); // 注意 target 符号
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 = 'selected';
}
});
// 12. 添加节流阀
});
动画
function animate(obj, target, callback) { // 多加一个形参(回调函数)
clearInterval(obj.timer);
obj.timer = setInterval(function () {
step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
clearInterval(obj.timer);
// 回调函数写在定时器结束里面
// if (callback) {
// callback()
// }
// 逻辑中断(短路运算符的使用),与上面的 if 表达式能实现相同的结果
callback && callback()
}
obj.style.left = obj.offsetLeft + step + 'px';
}, 15) // 一般写 15
}