一、选项卡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>选项卡</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
a {
text-decoration: none;
color: #555;
}
a:hover {
text-decoration: underline;
color: red;
}
li {
list-style: none;
line-height: 1.6em;
}
li:hover {
cursor: default;
}
.boxs {
width: 300px;
height: 300px;
margin: 30px;
background-color: #e6e6e6;
display: flex;
flex-direction: column;
}
.box {
height: 36px;
display: flex;
}
.box li {
flex: auto;
text-align: center;
line-height: 36px;
background-color: #fff;
}
.box li.active {
background-color: #e6e6e6;
}
.box li:hover {
cursor: pointer;
}
/* 默认所有选项卡只有一个显示,其它隐藏 */
.lanmu{
padding: 20px;
display: none;
overflow: hidden;
text-overflow: ellipsis;
white-space:nowrap;
}
.lanmu.active {
display: block;
}
</style>
</head>
<body>
<div class="boxs">
<!-- 导航 -->
<ul class="box">
<li class="active" data-index="1">国内</li>
<li data-index="2">国际</li>
<li data-index="3">军事</li>
<li data-index="4">财经</li>
<li data-index="5">体育</li>
</ul>
<!-- details -->
<ul data-index="1" class="lanmu active">
<li><a href="">新疆铁路南通道作用显现....</a></li>
<li><a href="">福建的第一次!</a></li>
<li><a href="">快递从业者也能成“高级工程师”?....</a></li>
<li><a href="">重庆人盼望下雪的心有多强烈?...</a></li>
<li><a href="">快递从业者也能成“高级工程师”?....</a></li>
<li><a href="">江苏南通:优化产业布局 护好长...</a></li>
</ul>
<ul data-index="2" class="lanmu">
<li><a href="">外交部批驳蓬佩奥又双叒叕散布谎言....</a></li>
<li><a href="">任期进入倒计时,蓬佩奥还在散播....</a></li>
<li><a href="">沙漠中一处“神秘”村庄,白天出现晚上消失,当地人不..</a></li>
<li><a href="">国外打出租车:上车要说“by meter”,否则可..</a></li>
<li><a href="">防止特朗普启动核武器!这场谈话触及五角大.....</a></li>
<li><a href="">白宫美女发言人“变脸” 网友:“化妆师集体.....</a></li>
</ul>
<ul data-index="3" class="lanmu">
<li><a href="">俄专家呼吁复活“核幽灵”列车....</a></li>
<li><a href="">印军多高官近期密集访问列城....</a></li>
<li><a href="">超燃现场!多型靶弹精准打击目标</a></li>
<li><a href="">穿越冰河 这些边防军人筑起钢铁....</a></li>
<li><a href="">美军无人机午夜侦察南海 至上午8....</a></li>
<li><a href="">中国海警舰艇编队1月13日在我钓.....</a></li>
</ul>
<ul data-index="4" class="lanmu">
<li><a href="">别样的挂历小店</a></li>
<li><a href="">丰台设50余个新冠肺炎疫苗临时接种点 已累计接...</a></li>
<li><a href="">北京奇案:40幅珍贵画作在香港某画展上神秘消失</a></li>
<li><a href="">美在耕耘——中国美术馆新年展”在京亮相</a></li>
<li><a href="">加大备货、推惠民菜,北京商超、生鲜电商硬核保供...</a></li>
<li><a href="">青岛新冠疫苗接种已达9万多人!市民将陆续免费接...</a></li>
</ul>
<ul data-index="5" class="lanmu">
<li><a href="">山西汾酒股份胜苏州肯帝亚</a></li>
<li><a href="">世界羽联更新防疫动态 内维尔等获准出战泰国赛</a></li>
<li><a href="">我们始终在路上——人大网球队</a></li>
<li><a href="">德国杯:勒沃库森胜法兰克福</a></li>
<li><a href="">澳网资格赛现阳性病例!</a></li>
<li><a href="">连救赛点!斯诺克大师赛颜丙涛6:5逆转罗伯逊进8强</a></li>
</ul>
</div>
<script>
// 事件代理
const box = document.querySelector(".box");
// 五个列表
const lanmus = document.querySelectorAll(".lanmu");
box.onclick = ev => {
// 事件的绑定对象
// console.log(ev.currentTarget);
// 事件触发对象
// console.log(ev.target);
// 只需要二步:
// 1. 清空之前所有处于激活状态的选项卡,并将当前点击对象激活
[...box.children].forEach(lanmu => lanmu.classList.remove("active"));
ev.target.classList.add("active");
// 2. 根据自定义属性data-index找到对应的列表并显示出来
// NodeList对象内置了forEach接口
lanmus.forEach(lanmu => lanmu.classList.remove("active"));
[...lanmus].filter(lanmu => lanmu.dataset.index === ev.target.dataset.index)[0].classList.add("active");
};
</script>
</body>
</html>
图示:
二、轮播图
<!DOCTYPE html>
<html lang="en">
<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");
skip.addEventListener("click", skipImg, false);
// 单独写一个事件监听器,为后面的事件自动派发做准备
skip.children[0].addEventListener("click", skipImg, false);
// 将前后翻页,使用一个回调统一处理
function skipImg(ev) {
// 当前激活的图片,实际上这里用不到它,而应该用它的父级<a>来判断是否存在兄弟节点
let currentImg = getActiveEle(imgs);
// 当前图片组父元素,注意<img>父级是<a>,<a>的父级才是需要的父节点
let parentEle = currentImg.parentElement.parentElement;
// 当前元素的前一个兄弟节点:previousElementSibling;
let prevEle = currentImg.parentElement.previousElementSibling;
// 当前元素的下一个兄弟节点:nextElementSibling;
let nextEle = currentImg.parentElement.nextElementSibling;
// 第一张图片, firstElementChild第一个子元素
let firstImg = parentEle.firstElementChild.firstElementChild;
// 最后一张图片, firstElementChild, 最后一个子元素
let lastImg = parentEle.lastElementChild.firstElementChild;
let activeImg = currentImg;
// 向前翻页
if (ev.target.classList.contains("prev")) {
// 如果存在前一张图片,就使用它,否则就使用最后一张图片来更新它,形成循环显示的效果
let activeImg =
prevEle !== null ? prevEle.firstElementChild : lastImg;
// 使用激活元素来同步更新图片与按钮
setActiveEle(activeImg.dataset.index);
}
// 向后翻页
if (ev.target.classList.contains("next")) {
// 如果不存在下一张图片,就用第一张图片更新它
let activeImg =
nextEle !== null ? nextEle.firstElementChild : firstImg;
setActiveEle(activeImg.dataset.index);
}
}
let timer = null;
const slider = document.querySelector(".container");
slider.addEventListener("mouseout", startTimer, false);
slider.addEventListener("mouseover", clearTimer, false);
// 启动定时器
function startTimer() {
// 创建自定义事件对象
const clickEvent = new Event("click");
timer = setInterval(
() => skip.children[0].dispatchEvent(clickEvent),
2000
);
}
// 清除定时器
function clearTimer() {
clearInterval(timer);
}
// 创建出一组与图片数量对应的小按钮
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)));
</script>
</body>
</html>
图示:
三、懒加载图片
body>
<div class="container">
<img src="images/temp.jpg" alt="" data-src="images/img-1.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-2.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-3.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-4.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-5.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-6.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-7.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-8.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-9.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-10.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-11.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-12.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-13.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-14.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-15.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-16.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-17.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-18.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-19.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-20.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-21.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-22.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-23.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-24.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-25.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-26.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-27.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-28.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-29.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-30.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-31.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-32.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-33.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-34.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-35.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-36.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-37.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-38.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-39.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-40.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-41.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-42.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-43.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-44.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-45.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-46.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-47.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-48.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-49.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-50.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-51.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-52.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-53.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-54.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-55.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-56.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-57.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-58.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-59.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-60.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-61.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-62.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-63.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-64.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-65.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-66.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-67.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-68.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-69.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-70.jpg" />
</div>
</body>
<script>
const imgs = document.querySelectorAll(".container img");
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>
图示: