实战:轮播图
<!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="banner/banner.css" />
</head>
<body>
<div class="container">
<!-- 1. 图片组 -->
<nav class="imgs">
<a href=""><img src="banner/banner1.jpg" alt="" data-index="1" class="active" /></a>
<a href=""><img src="banner/banner2.jpg" alt="" data-index="2" /></a>
<a href=""><img src="banner/banner3.jpg" alt="" data-index="3" /></a>
<a href=""><img src="banner/banner4.jpg" alt="" data-index="4" /></a>
</nav>
<!-- 2. 图片中下部的小按钮 -->
<nav class="btns">
<!-- 动态创建小按钮数量 -->
</nav>
<!-- 3. 翻页 -->
<nav class="skip">
<a href="" class="prev"><</a>
<a href="" class="next">></a>
</nav>
</div>
<script>
// 获取元素
const container = document.querySelector(".container");
const imgs = document.querySelectorAll(".container >.imgs img");
const btnGroup = document.querySelector(".container >.btns");
const skip = document.querySelector(".container >.skip");
// 创建出一组与图片数量对应的小按钮
function autoCreateBtns(ele, imgLength) {
const frag = document.createDocumentFragment();
for (let i = 0; i < imgLength; i++) {
const a = document.createElement("a");
a.href = "#";
a.dataset.index = i + 1;
if (i === 0) {
a.classList.add("active");
}
frag.append(a);
}
ele.append(frag);
}
autoCreateBtns(btnGroup, imgs.length);
// 为刚生成的小按钮添加点击事件
const btns = document.querySelectorAll(".container > .btns > *");
// 获取激活元素
function getActiveEle(eles) {
let activeEles = [...eles].filter(ele => ele.classList.contains("active"));
return activeEles.shift();
}
// 设置激活元素,根据按钮索引更新正在显示的图片
function setActiveEle(btnIndex) {
// 1.首先将之前的激活样式去掉
[imgs, btns].forEach(arr => {
getActiveEle(arr).classList.remove("active");
// 2.在根据当前自定义索引重新设置应该激活的按钮和图片
arr.forEach(item => {
if (item.dataset.index == btnIndex) {
item.classList.add("active");
}
});
});
}
// 为按钮添加事件
btns.forEach(btn => btn.addEventListener("click", ev => setActiveEle(ev.target.dataset.index)));
// 为翻页按钮添加点击事件,注意最后一张和第一张图片的边界处理
skip.onclick = ev => {
// 禁止默认的点击事件
ev.preventDefault();
// 获取当前显示图片的下标
let currIndex = getActiveEle(imgs).dataset.index;
// 下一页操作
if (ev.target.classList.contains("next")) {
let index = currIndex < imgs.length ? ++currIndex : 1;
setActiveEle(index);
return;
}
// 上一页操作
if (ev.target.classList.contains("prev")) {
let index = currIndex > 1 ? --currIndex : imgs.length;
setActiveEle(index);
return;
}
};
// 轮播图自动切换
// 使用setInterval()定时器实现图片的每隔 2 秒自动切换功能
var timer;
function autoChange() {
timer = setInterval(() => {
// 获取当前显示图片的下标
let currIndex = getActiveEle(imgs).dataset.index;
let index = currIndex < imgs.length ? ++currIndex : 1;
setActiveEle(index);
}, 2000);
}
autoChange();
// 监听鼠标移入事件和移出事件,实现鼠标悬停在图片上时,停止自动切换,停留在当前图片
container.addEventListener("mouseenter", () => clearInterval(timer));
// 鼠标移出时继续自动切换
container.addEventListener("mouseleave", autoChange);
</script>
</body>
</html>
banner.css 文件:
/* 初始化 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
a {
text-decoration: none;
}
/* 轮播图的容器 */
.container {
width: 62.5em;
height: 22em;
margin: 1em auto;
/* 转为定位元素/定位父级 */
position: relative;
}
/* 图片组 */
.container > .imgs img {
width: 100%;
height: 100%;
/* 默认全部隐藏 */
display: none;
/* 将所有的图片进行绝对定位,确保每一次只看到一张,所有图片共享这个容器 */
position: absolute;
left: 0;
top: 0;
}
/* 设置默认显示的图片(第一张) */
.container > .imgs img.active {
display: block;
}
/* 按钮组(独立按钮) */
.container > .btns {
position: absolute;
left: 0;
right: 0;
bottom: 0;
/* 水平居中 */
text-align: center;
}
.container > .btns a {
/* 转成行内块元素: 即能水平排列,双支持宽度设置 */
display: inline-block;
padding: 0.5em;
margin: 0 0.2em;
background-color: #fff;
border-radius: 50%;
}
.container > .btns a.active {
background-color: #000;
}
/* 翻页按钮 */
.container .skip a {
position: absolute;
width: 2.5rem;
height: 5rem;
line-height: 5rem;
text-align: center;
opacity: 0.3;
top: 9rem;
font-weight: lighter;
font-size: 2rem;
background-color: #ccc;
}
.container .skip .prev {
left: 0;
}
.container .skip .next {
right: 0;
}
.container .skip *:hover {
opacity: 0.6;
color: #666;
}