案例演示
轮播图功能需求:
-
鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮;
-
点击右侧按钮一次,图片往左播放一张,以此类推,左侧按钮同理;
-
图片播放的同时,下面小圆圈模块跟随一起变化;
-
点击小圆圈,可以播放相应图片;
-
鼠标不经过轮播图,轮播图也会自动播放图片;
-
鼠标经过,轮播图模块, 自动播放停止。
代码实现
css
* {
padding: 0;
margin: 0;
}
a {
text-decoration: none;
color: #ccc;
}
ul,
ol {
list-style: none;
}
.focus {
position: relative;
width: 590px;
/* 需要设置高度之后绝对子元素绝对定位才能使用百分比 */
height: 470px;
margin: 100px auto;
overflow: hidden;
}
.focus li img {
width: 100%;
}
.arrow-left,
.arrow-right {
display: none;
position: absolute;
top: 50%;
width: 38px;
height: 38px;
line-height: 38px;
text-align: center;
color: #fff;
font-weight: 700;
cursor: pointer;
background-color: rgba(0, 0, 0, .3);
transform: translateY(-50%);
transition: all 1s linear;
z-index: 2;
}
.arrow-left:hover,
.arrow-right:hover {
color: #ccc;
}
.arrow-left {
left: 0;
border-radius: 0 15px 15px 0;
}
.arrow-right {
right: 0;
border-radius: 15px 0 0 15px;
}
.focus ul {
position: absolute;
top: 0;
left: 0;
width: 600%;
}
.focus ul li {
float: left;
}
.focus ol {
position: absolute;
bottom: 16px;
left: 50%;
/* 移动自身宽度的50% */
transform: translateX(-50%);
}
.focus ol li {
float: left;
margin-right: 10px;
width: 5px;
height: 5px;
border-radius: 50%;
cursor: pointer;
border: 3px solid rgba(255, 255, 255, .5);
}
.focus ol li.cur_point {
background-color: #fff;
border-color: #ffffff;
}
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"
,maximum-scale=1.0,minimum-scale=1.0>
<title>网页轮播图</title>
<link rel="stylesheet" href="css/index.css">
<link rel="stylesheet" href="css/iconfont.css">
<script src="./js/animation.js"></script>
<script src="./js/index.js"></script>
</head>
<body>
<div class="focus">
<!-- javascript:void(0); 阻止页面跳转 -->
<a href="javascript:void(0);" class="arrow-left">
<i class="iconfont icon-zuoyou"></i>
</a>
<a href="javascript:void(0);" class="arrow-right">
<i class="iconfont icon-icon-you"></i>
</a>
<ul>
<li><a href="javascript:void(0);"><img src="images/focus1.jpg.webp" alt=""></a></li>
<li><a href="javascript:void(0);"><img src="images/focus4.jpg.webp" alt=""></a></li>
<li><a href="javascript:void(0);"><img src="images/focus2.jpg.webp" alt=""></a></li>
<li><a href="javascript:void(0);"><img src="images/focus3.jpg.webp" alt=""></a></li>
</ul>
<ol></ol>
</div>
</body>
</html>
javascript
/**
* 绑定页面加载完成之后再指定js的事件
*/
window.addEventListener('load', () => {
// 获取元素
let focus = document.querySelector('.focus');
let ul = focus.querySelector('ul');
let arrowRight = focus.querySelector('.arrow-right');
let arrowLeft = focus.querySelector('.arrow-left');
let focusWidth = focus.offsetWidth;
let lisSize = ul.children.length;
let ol = focus.querySelector('ol');
let time = 1000;
/**
* 当鼠标接触到轮播图的时候显示左右切换按钮
*/
focus.addEventListener('mouseenter', () => {
arrowRight.style.display = 'block';
arrowLeft.style.display = 'block';
// 当鼠标进入时清除定时器
clearInterval(timer);
timer = null;
})
/**
* 当鼠标离开轮播图的时候隐藏左右切换按钮
*/
focus.addEventListener('mouseleave', () => {
arrowRight.style.display = 'none';
arrowLeft.style.display = 'none';
/**
* 当鼠标离开的时候重新设置定时器
* @type {number}
*/
timer = setInterval(() => {
arrowRight.click();
}, time);
})
/**
* 根据ul中 li 的个数创建 ol中li的个数小圆点
*/
for (let i = 0; i < lisSize; i++) {
// 创建一个节点
let li = document.createElement('li');
// 为每一个 li 设置自定义属性
li.setAttribute('data-index', i + '');
// 追加节点
ol.appendChild(li);
/**
* 为每一个小圆点注册点击事件选中时,出现未选中状态
*/
ol.children[i].addEventListener('click', () => {
for (let i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[i].className = 'cur_point';
// 获取自定义属性
let dataIndex = ol.children[i].getAttribute('data-index');
// 调用动画进行切换
animation(ul, -dataIndex * focusWidth)
// 将 num 赋值为当前自定义属性
num = dataIndex;
circle = dataIndex;
})
}
// 在这里设置因为上面刚创建了 li 添加到 ol 中
ol.children[0].className = 'cur_point';
// 将子第一个节点深拷贝到最后
let firstLi = ul.children[0].cloneNode(true);
// 将该节点添加到ul的后面
ul.appendChild(firstLi);
let circle = 0;
let num = 0;
// 节流阀: 利用回调函数原理需要执行完上一件事之后再执行下一件事
let flag = true;
/**
* 向右切换图片
*/
arrowRight.addEventListener('click', (e) => {
if (flag) {
// 关闭水龙头
flag = false;
if (num >= lisSize) {
num = 0;
ul.style.left = 0 + 'px';
}
num++;
animation(ul, -(num * focusWidth), () => {
// 执行回调函数 打开水龙头
flag = true;
});
circle++;
if (circle >= lisSize) {
circle = 0
}
curPoint(circle);
}
})
/**
* 向左切换图片
*/
arrowLeft.addEventListener('click', () => {
if (flag) {
flag = false;
if (num <= 0) {
num = lisSize;
// 当前 ul 距离左侧的距离是
ul.style.left = -(num * focusWidth) + 'px';
}
num--;
animation(ul, -(num * focusWidth), () => {
flag = true;
});
circle--;
if (circle < 0) {
circle = lisSize - 1;
}
curPoint(circle);
}
})
/**
* 将当前点设置为选中状态
* @param index
*/
function curPoint(index) {
for (let i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
ol.children[index].className = 'cur_point';
}
}
/**
* 向右切换的 调用默认点击
* @type {number}
*/
let timer = setInterval(() => {
arrowRight.click();
}, time)
})
animation.js 实现切换图片动画,实现了一个缓动动画
function animation(obj,target,callback) {
clearInterval(obj.timer);
obj.timer = setInterval(()=> {
// 计算步长
let step = (target - obj.offsetLeft) / 10;
// 判断当前的步长是否大于 0 大于0 则向上取整,反之向下取整
step = step > 0 ? Math.ceil(step) : Math.floor(step);
// 设置 元素对象的 left 属性使盒子移动
obj.style.left = obj.offsetLeft + step + 'px';
// 判断移动的距离是否查出目标值 如果超出则将定时器移除
if (obj.offsetLeft === target) {
clearInterval(obj.timer);
callback && callback(); // 相当于 if(callback) {callback()}
// 动画执行完成之后再执行回调函数
}
},15)
}
网友评论