效果示例:
实现思路:
- 获取元素对象,可以使用querySelector
- 根据切换的图片数量,动态生成相应个数的小圆点,for循环实现,并且给小圆点的标签添加属性“index”,记录圆点位置,
- 克隆第一张图片,添加到最后一张图片后:
左移效果- - -从最后一张图片切换到第一张图,其实在图片最后多添加了一个撕一张图,先移动到后面多添加的一张,然后再快速跳到第一张图 - 使用变量控制图片(num)和小圆点(circle)的滚动,以及限制动画播放速度(节流阀,一个布尔值变量,如flag)
- 右箭头添加点击事件,每次点击,向左移动一个图片宽度,如果是最后一张图片,跳到第一张,然后移动到第二张,移动后num、circle自增1,改变小圆圈样式,当前位置为选中状态
- 左箭头绑定点击事件,如果是第一张图片,跳到第一张,然后移动到最后一张,后num、circle自减1,改变小圆圈样式,当前位置为选中状态
- 左右箭头点击事件中均使用节流阀,控制切换速度,flag初始值为true,点击箭头后,值设为false,当动画执行完毕后,回调函数中又将flag值改为true,只有当flag为true时,点击箭头才切换,保证一次动画没执行完时,点击不会重新开启动画,动画不叠加就不会产生多次点击动画加速效果
- 小圆圈样式变化,排他思想,单独一个函数控制,用的时候调用
- 使用setInterval函数,里面手动调用点击事件,如- - -arrow_r.click();实现自动播放轮播图效果
- 绑定事件,鼠标移动到轮播图区显示左右箭头,图片停止切换
- 绑定事件,鼠标离开轮播图区后隐藏左右箭头,图片自动切换
实现代码示例:
结构:
1.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="box">
<div class="focus">
<a href="javascript:;" class="arrow_l icomoon"></a>
<a href="javascript:;" class="arrow_r icomoon"></a>
<ul>
<li><img src="images/头像2.jpg" alt=""></li>
<li><img src="images/头像3.jpg" alt=""></li>
<li><img src="images/头像4.jpg" alt=""></li>
<li><img src="images/头像5.jpg" alt=""></li>
</ul>
<ol></ol>
</div>
</div>
</body>
</html>
2.index.css:
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
a {
text-decoration: none;
}
/* 字体图标 */
@font-face {
font-family: 'icomoon';
src: url('../fonts/icomoon.eot?go45v8');
src: url('../fonts/icomoon.eot?go45v8#iefix') format('embedded-opentype'), url('../fonts/icomoon.ttf?go45v8') format('truetype'), url('../fonts/icomoon.woff?go45v8') format('woff'), url('../fonts/icomoon.svg?go45v8#icomoon') format('svg');
font-weight: normal;
font-style: normal;
font-display: block;
}
.icomoon {
font-family: 'icomoon';
font-style: normal;
}
.box {
width: 960px;
margin: 0 auto;
}
/* 轮播图 */
.focus {
position: relative;
width: 300px;
height: 300px;
margin: 100px auto;
overflow: hidden;
}
.focus ul {
position: absolute;
top: 0;
left: 0;
width: 600%;
}
.focus ul li {
float: left;
width: 300px;
height: 300px;
}
.focus ul li img {
width: 100%;
height: 100%;
}
/* 左右箭头 */
.arrow_l,
.arrow_r {
position: absolute;
width: 30px;
height: 30px;
line-height: 30px;
top: 50%;
transform: translateY(-50%);
color: #fff;
background-color: rgba(0, 0, 0, .5);
z-index: 2;
}
.arrow_l {
left: 0;
text-align: left;
}
.arrow_r {
right: 0;
text-align: right;
}
/* 小圆点 */
.focus ol {
position: absolute;
bottom: 8px;
left: 50%;
padding: 5px;
transform: translateX(-50%);
/* background: rgba(255, 255, 255, .3); */
background-color: rgba(0, 0, 0, .5);
border-radius: 15px;
}
.focus ol li {
float: left;
width: 10px;
height: 10px;
margin: 0 5px;
border-radius: 10px;
/* background: rgba(0, 0, 0, .5); */
border: 1px solid #fff;
}
.current {
background-color: #fff;
}
3.字体图标- - -fonts文件夹,可以到icomoon官网下载
4.animate.js:
function animate(obj, target, callback) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
// 缓速运动
var step = (target - obj.offsetLeft) / 10;
step = step < 0 ? Math.floor(step) : Math.ceil(step);
// 达到目标位置后,停止运动
if (obj.offsetLeft == target) {
clearInterval(obj.timer);
// 有回调函数的话,执行回调函数
callback && callback();
}
obj.style.left = obj.offsetLeft + step + 'px';
}, 15);
}
5.index.js:
window.addEventListener('load', function() {
// 1. 获取元素
var focus = document.querySelector('.focus');
var ul = focus.querySelector('ul')
var ol = focus.querySelector('ol');
var arrow_l = focus.querySelector('.arrow_l');
var arrow_r = focus.querySelector('.arrow_r');
var focusWidth = focus.offsetWidth;
// console.log(focusWidth);
// 2. 动态生成小圆点
for (var i = 0; i < ul.children.length; i++) {
var li = document.createElement('li');
li.setAttribute('index', i);
ol.appendChild(li);
// 给小圆点绑定点击事件,切换到相应图片
li.addEventListener('click', function() {
var index = this.getAttribute('index');
num = index;
circle = index;
circleChange();
animate(ul, -index * focusWidth);
})
}
// 3. 克隆第一张图片,添加到最后一张图片后
var lastPic = ul.children[0].cloneNode(true);
ul.appendChild(lastPic);
// 4. 使用变量控制图片和小圆点的滚动,以及限制动画播放速度
// 控制图片的滚动,记录移动图片张数
var num = 0;
// 控制小圆圈的滚动
var circle = 0;
// 创建节流阀,控制动画速度
var flag = true;
ol.children[circle].className = 'current';
// 5. 右箭头
arrow_r.addEventListener('click', function() {
if (flag) {
// 关闭节流阀
flag = false;
// 如果是最后一张图片,跳到第一张,然后移动到第二张
if (num == ul.children.length - 1) {
num = 0;
ul.style.left = 0;
}
num++;
animate(ul, -num * focusWidth, function() {
flag = true;
});
circle++;
if (circle == ol.children.length) {
circle = 0;
}
// 调用函数,改变小圆圈样式
circleChange();
}
})
// 6. 左箭头
arrow_l.addEventListener('click', function() {
if (flag) {
// 关闭节流阀
flag = false;
// 如果是第一张图片,跳到第一张,然后移动到最后一张
if (num == 0) {
num = ul.children.length - 1;
ul.style.left = -num * focusWidth + 'px';
}
num--;
animate(ul, -num * focusWidth, function() {
flag = true;
});
circle--;
circle = circle < 0 ? ol.children.length - 1 : circle;
// 调用函数,改变小圆圈样式
circleChange();
}
})
// 7. 小圆圈样式变化,排他思想
function circleChange() {
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[circle].className = 'current';
}
// 8. 自动播放轮播图
var timer = setInterval(function() {
// 手动调用点击事件
arrow_r.click();
}, 2000);
// 9. 绑定事件,鼠标移动到轮播图区显示左右箭头
focus.addEventListener('mouseenter', function() {
arrow_l.style.display = 'block';
arrow_r.style.display = 'block';
clearInterval(timer);
timer = null;
})
// 10. 绑定事件,鼠标离开轮播图区后隐藏左右箭头
focus.addEventListener('mouseleave', function() {
arrow_l.style.display = 'none';
arrow_r.style.display = 'none';
timer = setInterval(function() {
arrow_r.click();
}, 2000);
})
})