主要内容:
- tabs
- 懒加载
- 轮播图
- 几个要点:
- index的绑定
- class的妙用 - 通过add、remove元素的class的名称来获得高亮等属性
- 懒加载中的具体位置计算
1. tabs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>经典选项卡案例</title>
<style>
@import url(static/css/tabs.css);
</style>
</head>
<body>
<!-- 导航区 -->
<div class="tabs">
<ul class="tab">
<li class="active" data-index="1">水果</li>
<li data-index="2">手机</li>
<li data-index="3">汽车</li>
</ul>
<!-- 水果对应的详情区 -->
<ul class="item active" data-index="1">
<li><a href="">西瓜</a></li>
<li><a href="">苹果</a></li>
<li><a href="">橙子</a></li>
</ul>
<!-- 手机对应的详情区 -->
<ul class="item" data-index="2">
<li><a href="">华为</a></li>
<li><a href="">小米</a></li>
<li><a href="">OPPO</a></li>
</ul>
<!-- 汽车对应的详情区 -->
<ul class="item" data-index="3">
<li><a href="">奇瑞</a></li>
<li><a href="">吉利</a></li>
<li><a href="">江淮</a></li>
</ul>
</div>
<script src="static/js/tabs.js"></script>
</body>
</html>
- css文件
* {
margin: 0;
padding: 0;
}
a {
text-decoration: none;
color: #555;
}
a:hover {
text-decoration: underline;
color: red;
}
li {
list-style: none;
}
li:hover {
cursor: default;
}
.tabs {
width: 300px;
height: 300px;
margin: 30px;
background-color: #ddd;
display: flex;
flex-direction: column;
}
.tab {
height: 36px;
display: flex;
}
.tab li {
flex: auto;
text-align: center;
line-height: 36px;
background-color: #fff;
}
.tab li.active {
background-color: #ddd;
}
/* 默认所有选项卡只有一个显示,其它隐藏 */
.item {
padding: 20px;
display: none;
}
.item.active {
display: block;
}
- js部分
// 1. 获取导航
var tab = document.querySelector(".tab");
// console.log(tab);
// 2. 获取详情页
var items = document.querySelectorAll(".item");
// console.log(items);
// 3. 给导航添加点击事件(事件代理/事件委托/冒泡)
tab.addEventListener("click", show, false);
tab.addEventListener("mouseover", show, false);
// 4. 声明show()函数
function show(ev) {
// ev: 事件对象
// ev.type: 事件类型,如click,mouseover,input....
// console.log(ev.type);
// ev.target: 事件的触发者
// console.log(ev.target);
// ev.currentTarget: 事件绑定者
// console.log(ev.currentTarget);
// 4-1. 清除除当前高亮选项卡之外的选项卡的高亮样式
// console.log(ev.currentTarget.children);
ev.currentTarget.childNodes.forEach(function (item) {
if (item.nodeType === 1) item.classList.remove("active");
}); // 1标示是非text的元素,也就是正常的元素
// 4-2. 应该将用户点击的当前选项卡高亮显示
ev.target.classList.add("active");
// 4-3. 清空原有列表
items.forEach(function (item) {
item.classList.remove("active");
});
// 4-4. 将选项卡对应的内容进行切换(根据导航和详情中的data-index)
items.forEach(function (item) {
// console.log(item);
// console.log(ev.target.dataset.index, item.dataset.index);
if (ev.target.dataset.index === item.dataset.index) {
item.classList.add("active");
}
});
}
2. 懒加载
- 基本原理
<!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="static/css/lazy-base.css" />
</head>
<body>
<div class="parent">
<div class="child"></div>
</div>
<script>
var parent = document.querySelector(".parent");
var child = document.querySelector(".child");
// 1. 这四个属性的值,与css样式相关
console.log("元素的高度: ", child.offsetHeight);
console.log("元素的宽度: ", child.offsetWidth);
console.log("距离父元素的左偏移量: ", child.offsetLeft);
console.log("距离父元素的顶部偏移量: ", child.offsetTop);
// 2. 元素内容区大小
// content + padding
console.log(child.clientHeight);
console.log(child.clientWidth);
console.log(document.documentElement.clientHeight);
</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>
</head>
<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-70.jpg" />
</div>
<script>
// 1. 获取所有的图片
// 用css选择器选择图片,class前面需要有.,但如果是tab则不需要。
var imgs = document.querySelectorAll(".container img");
// 2. 获取文档的高度
var clientHeight = document.documentElement.clientHeight;
// 3. 监听滚动事件
window.addEventListener("scroll", function () {
lazyload(imgs, clientHeight);
},
false
);
// 4. 懒加载函数
function lazyload(imgs, clientHeight) {
// 获取文档的滚动大小
var scrollTop = document.documentElement.scrollTop;
// 遍历图片,判断是否进入到可视区
// 下面这个公式很重要,clientHeight指的就是浏览器的可视区高度
// scrollTop则是页面卷上去的高度吧
imgs.forEach(function (img) {
if (img.offsetTop <= clientHeight + scrollTop) {
img.src = img.dataset.src;
}
});
}
</script>
</body>
</html>
.parent {
height: 400px;
width: 300px;
padding: 5px;
background-color: lightblue;
border: 5px solid;
overflow: scroll;
position: relative;
}
.parent .child {
height: 500px;
width: 400px;
padding: 5px;
background-color: lightgreen;
background-clip: content-box;
border: 5px solid;
position: relative;
left: 10px;
top: 20px;
}
3. 轮播
- 轮播的要点:
- a-下面的小圆点及高亮;
- b-左右的切换;
- c-active被通过class名称的方式来改变属性
<!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="static/css/slider.css" />
</head>
<body>
<div class="box">
<img src="banner/banner1.jpg" alt="" data-index="1" class="slider active"/>
<img src="banner/banner2.jpg" alt="" data-index="2" class="slider" />
<img src="banner/banner3.jpg" alt="" data-index="3" class="slider" />
<img src="banner/banner4.jpg" alt="" data-index="4" class="slider" />
<div class="point-list">
<!-- 下面这段小圆点是通过js动态生成的,因为要跟具体图片的数量报纸一致,
并且index要跟图片对应起来 -->
<!-- <span class="point active" data-index="1"></span>
<span class="point" data-index="2"></span>
<span class="point" data-index="3"></span> -->
</div>
<span class="skip prev"><</span>
<span class="skip next">></span>
</div>
<script src="static/js/slider.js"></script>
</body>
</html>
ul,
li {
margin: 0;
padding: 0;
list-style: none;
}
.box {
/*定位父级*/
position: relative;
width: 1000px;
height: 350px;
margin: 0 auto;
}
.box .slider {
width: 1000px;
height: 350px;
display: none;
}
.box .slider.active {
display: block;
}
.box .point-list {
position: absolute;
/*绝对定位的环境下的水平居中方式*/
left: 50%;
margin-left: -38px;
top: 310px;
}
.box .point-list .point {
display: inline-block;
width: 12px;
height: 12px;
margin: 0 5px;
background-color: white;
border-radius: 100%;
}
.box .point-list .point.active {
background-color: black;
}
.box .point-list .point:hover {
cursor: pointer;
}
.skip {
position: absolute;
top: 140px;
display: inline-block;
width: 40px;
height: 80px;
text-align: center;
line-height: 80px;
background-color: lightgray;
color: white;
opacity: 0.2;
font-size: 36px;
}
.box .prev {
left: 0;
}
.box .next {
right: 0;
}
.box .skip:hover {
cursor: pointer;
opacity: 0.5;
color: black;
}
// 获取轮播图片
var imgs = document.querySelectorAll("img");
// 获取小圆点组
var pointList = document.querySelector(".point-list");
// 动态生成小圆点
imgs.forEach(function(img, index) {
var span = document.createElement("span");
if (index == 0) span.classList.add("point", "active");
span.classList.add("point");
// 给当前的小圆点添加自定义的data-index
span.dataset.index = img.dataset.index;
pointList.appendChild(span);
});
// 获取到所有的小圆点
var points = document.querySelectorAll(".point");
// 给小圆点添加事件(代理)
pointList.addEventListener("click", function (ev) {
imgs.forEach(function (img) {
if (img.dataset.index === ev.target.dataset.index) {
imgs.forEach(function (img) {
img.classList.remove("active"); // 先将其他的高亮取消掉。
});
img.classList.add("active");
// 设置与当前图片对应的小圆点高亮显示
// 因为这个功能要多处使用,这里将它声明为公共函数
setPointActive(img.dataset.index);
}
});
});
// 设置与当前图片对应的小圆点高亮显示;
function setPointActive(imgIndex) {
points.forEach(function (point) {
point.classList.remove("active");
});
points.forEach(function (point) {
if (point.dataset.index === imgIndex) point.classList.add("active");
});
}
// ----------------- 翻页功能 -----------------
// 获取翻页按钮
var skip = document.querySelectorAll(".skip");
// 添加事件
skip.item(0).addEventListener("click", skipImg, false);
skip.item(1).addEventListener("click", skipImg, false);
// 翻页显示图片的回调方法
function skipImg(ev) {
// 1. 获取当前的图片
var currentImg = null;
imgs.forEach(function (img) {
if (img.classList.contains("active")) {
currentImg = img; // 选择目前激活的图片并显示
}
});
// console.log(currentImg);
// 2. 判断是否是点击了显示前一张的按钮?
if (ev.target.classList.contains("prev")) {
// 为了显示出来前一张,必须将当前图片的激活去掉
currentImg.classList.remove("active");
// 将当前图片的前一张图片设置为当前图片
currentImg = currentImg.previousElementSibling;
// console.log(currentImg);
// 如果存在前一张,再显示它,否则进入循环,显示最后一张
if (currentImg !== null && currentImg.nodeName === "IMG") {
currentImg.classList.add("active");
} else {
currentImg = imgs[imgs.length - 1];// 返回到最后一张图片
currentImg.classList.add("active");
}
}
// 3. 判断是否是点击了显示下一张的按钮?
if (ev.target.classList.contains("next")) {
// 为了显示出来前一张,必须将当前图片的激活去掉
currentImg.classList.remove("active");
// 将当前图片的前一张图片设置为当前图片
currentImg = currentImg.nextElementSibling;
// console.log(currentImg);
// 如果存在下一张,再显示它,否则进入循环,显示第一张
if (currentImg !== null && currentImg.nodeName === "IMG") {
currentImg.classList.add("active");
} else {
currentImg = imgs[0]; // 返回到了第一张图片
currentImg.classList.add("active");
}
}
// 小圆点高亮
setPointActive(currentImg.dataset.index);
}
4. 作业:
- 给轮播图添加自动播放功能,要求鼠标移入时自动停止播放并等用户操作
- 鼠标移出时, 2秒后自动播放
间歇式定时器
setInterval(function(){}, 时间)
// 自动轮播图
let autoStart = setInterval(autoSlide, 1000);
function autoSlide(){
var currentImg = null;
imgs.forEach(function (img) {
if (img.classList.contains("active")) {
currentImg = img;
currentImg.classList.remove("active");
}});
currentImg = currentImg.nextElementSibling;
if (currentImg !== null && currentImg.nodeName === "IMG") {
currentImg.classList.add("active");
} else {
currentImg = imgs[0];
currentImg.classList.add("active");
}
setPointActive(currentImg.dataset.index);
}
// imgs.addEventListener("mouseover",function(){clearInterval(autoStart);}, false);
// imgs.addEventListener("mouseout", function(){autoStart = setInterval(autoSlide, 2000);}, false);
// 貌似直接利用imgs不行。box才可以。
box = document.querySelector(".box");
box.addEventListener("mouseover", function(){clearInterval(autoStart);}, false);
box.addEventListener("mouseout", function(){autoStart = setInterval(autoSlide, 1000);}, false);