轮播图
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>轮播图</title>
<link rel="stylesheet" href="banner/style.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">
<!-- 这些小按钮应该根据图片数量自动生成 -->
<!-- <a href="" data-index="1" class="active"></a>
<a href="" data-index="2"></a>
<a href="" data-index="3"></a>
<a href="" data-index="4"></a> -->
</nav>
<!-- 3. 翻页 -->
<nav class="skip">
<a href="#" class="prev"><</a>
<a href="#" class="next">></a>
</nav>
</div>
<script>
// 获取所需元素
// 所有图片
const imgs = document.querySelectorAll(".container > .imgs img");
// 按钮组
const btnGroup = document.querySelector(".container > .btns");
// 翻页按钮
const skip = document.querySelector(".container > .skip");
// const skip = document.querySelectorAll(".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.appendChild(a);
}
ele.appendChild(frag);
}
// 调用创建小按钮的函数
autoCreateBtns(btnGroup, imgs.length);
// 为刚刚生成的小按钮们添加点击事件
const btns = document.querySelectorAll(".container > .btns > *");
// 下面声明二个公共函数
// 1. 获取激活的元素
function getActiveEle(eles) {
let activities = [...eles].filter(img => img.classList.contains("active"));
return activities.shift();
}
// 2. 设置激活的元素,根据按钮索引更新正在显示的图片
function setActiveEle(btnIndex) {
[imgs, btns].forEach(arr => {
// 将之前的状态全部重置到初始化(清空)
getActiveEle(arr).classList.remove("active");
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.addEventListener("click", skipImg, false);
console.log(skip.children[1]);
// 将前后翻页,使用一个回调统一处理
function skipImg(ev) {
// 当前激活的图片,实际上这里用不到它,而应该用它的父级<a>来判断是否存在兄弟节点
let currentImg = getActiveEle(imgs);
// 当前图片组父元素,注意<img>父级是<a>,<a>的父级才是需要的父节点
let parentEle = currentImg.parentElement.parentElement;
// 当前元素的前一个兄弟节点:previousElementSibling;
let prevEle = currentImg.parentElement.previousElementSibling;
// console.log(prevEle);
// 当前元素的下一个兄弟节点:nextElementSibling;
let nextEle = currentImg.parentElement.nextElementSibling;
// console.log(nextEle);
// 第一张图片, firstElementChild第一个子元素
let firstImg = parentEle.firstElementChild.firstElementChild;
// 最后一张图片, firstElementChild, 最后一个子元素
let lastImg = parentEle.lastElementChild.firstElementChild;
// console.log(lastImg);
let activeImg = currentImg;
// console.log(activeImg);
// 向前翻页
if (ev.target.classList.contains("prev")) {
// console.log(ev.target.classList.contains("prev"));
// 如果存在前一张图片,就使用它,否则就使用最后一张图片来更新它,形成循环显示的效果
let activeImg = prevEle !== null ? prevEle.firstElementChild : lastImg;
// 使用激活元素来同步更新图片与按钮
// console.log(activeImg.dataset.index);
setActiveEle(activeImg.dataset.index);
}
// 向后翻页
if (ev.target.classList.contains("next")) {
// 如果不存在下一张图片,就用第一张图片更新它
let activeImg = nextEle !== null ? nextEle.firstElementChild : firstImg;
setActiveEle(activeImg.dataset.index);
}
}
// 让图片每隔2秒进行自动播放(使用定时器,事件自动派发)
// 单独写一个事件监听器,为后面的事件自动派发做准备
skip.children[1].addEventListener("load", skipImg, false);
let timer = null;
const slider = document.querySelector(".container");
slider.addEventListener("mouseout", startTimer, false);
window.addEventListener("load", startTimer);
slider.addEventListener("mouseover", clearTimer, false);
// 启动定时器
function startTimer() {
// 创建自定义事件对象
const clickEvent = new Event("load");
timer = setInterval(() => skip.children[1].dispatchEvent(clickEvent), 2000);
}
// 清除定时器
function clearTimer() {
clearInterval(timer);
}
</script>
</body>
</html>
懒加载
<script>
// querySelectorAll自带forEach借口,可以直接便利
const imgs = document.querySelectorAll(".container img");
// clientHeight:视口高度 scrollTop:滚动高度
const clientHeight = document.documentElement.clientHeight;
// 实现懒加载
window.addEventListener("scroll", layzyload);
// load:页面加载完成自动执行
window.addEventListener("load", layzyload);
function layzyload() {
// 得到滚动高度
let scrollTop = document.documentElement.scrollTop;
// 遍历图片并判断是否进入到了可视区
imgs.forEach(img => {
// 只要当前图片距离文档顶部的偏移量,小于可视区高度与滚动高度之间则表示进入到可视区,应该显示出来
// clientHeight是可视区高度,这是一个固定的值,滚动高度是动态的
if (img.offsetTop < clientHeight + scrollTop) {
setTimeout(() => (img.src = img.dataset.src), 500);
}
});
}
</script>