Correcting teacher:天蓬老师
Correction status:qualified
Teacher's comments:为了便于记忆和理解 , 咱们的js代码都是精简且高效, 脚本并不是越多越好, 要注意效率
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>javaScript 轮播图 选项卡 懒加载</title>
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<div class="box">
<div class="bannerBox">
<img src="images/banner/banner1.jpg" alt="" data-index='1' class="slider active">
<img src="images/banner/banner2.jpg" alt="" data-index='2' class="slider">
<img src="images/banner/banner3.jpg" alt="" data-index='3' class="slider">
<img src="images/banner/banner4.jpg" alt="" data-index='4' class="slider">
<div class="pointList">
<!-- 图片对应的小圆点应该按照图片的个数动态生成 -->
<!-- <span class="point active"></span>
<span class="point"></span>
<span class="point"></span>
<span class="point"></span> -->
</div>
<span class="skip prev"><</span>
<span class="skip next">></span>
</div>
<!-- 轮播图的js代码 -->
<script src="js/banner.js"></script>
<!-- 选项卡和图片延时加载 -->
<div class="main">
<!-- 选项卡 -->
<div class="tabCard">
<div class="tab">
<div class="active" data-food-index="1">凉菜</div>
<div data-food-index="2">热菜</div>
<div data-food-index="3">甜品</div>
<div data-food-index="4">酒水</div>
</div>
<div class="item active" data-food-index="1">
<div>五香酱牛肉</div>
<div>凉拌笋丝</div>
<div>果仁菠菜</div>
<div>大拌菜</div>
</div>
<div class="item" data-food-index="2">
<div>宫爆鸡丁</div>
<div>鱼香肉丝</div>
<div>锅包肉</div>
<div>木须肉</div>
</div>
<div class="item" data-food-index="3">
<div>蛋糕</div>
<div>冰淇淋</div>
<div>蛋挞</div>
<div>饼干</div>
</div>
<div class="item" data-food-index="4">
<div>橙汁</div>
<div>啤酒</div>
<div>二锅头</div>
<div>雪碧</div>
</div>
</div>
<!-- 选项卡的js代码 -->
<script src="js/tabCard.js"></script>
<!-- 图片延时加载 -->
<div class="imgBox" onscroll="">
<?php for($i=1;$i<=70;$i++):?>
<img src="images/lazoyLoad/temp.jpg" alt="" data-src="<?php echo 'images/lazoyLoad/img-'.$i.'.jpg'; ?>">
<?php endfor;?>
</div>
<!-- 图片延时加载js代码 -->
<script src="js/lazyLoad.js"></script>
</div>
<!-- 评论区 -->
<div class="commentBox">
<textarea name="" id="" cols="165" rows="10" placeholder="输入评论"></textarea>
<button>发表评论</button>
<div class="comm">
<!-- <div class="item">
<span>写的好棒</span>
<button>删除</button>
</div>
<div class="item">
<span>写的好棒</span>
<button>删除</button>
</div>
<div class="item">
<span>写的好棒</span>
<button>删除</button>
</div> -->
</div>
</div>
<script src="js/comment.js"></script>
</div>
</body>
</html>
* {
padding: 0px;
margin: 0px;
box-sizing: border-box;
font-size: 12px;
}
.box {
width: 1020px;
min-height: 600px;
margin-top: 5px;
margin-left: auto;
margin-right: auto;
}
/* 轮播图 */
.box > .bannerBox {
/* 轮播图相对定位,为了定位其中的上一张,下一张和图片圆点的位置 */
position: relative;
width: 100%;
height: 350px;
}
/* 轮播图图片 */
.box > .bannerBox > .slider {
width: 100%;
height: 350px;
display: none;
}
.box > .bannerBox > .slider.active {
display: block;
}
/* 轮播图上图片对应的圆点 */
.box > .bannerBox > .pointList {
position: absolute;
left: 50%;
top: 330px;
}
.box > .bannerBox > .pointList .point {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 100%;
margin: 0px 5px;
background-color: white;
}
.box > .bannerBox > .pointList .point.active {
background-color: black;
}
.box > .bannerBox > .pointList .point:hover {
cursor: pointer;
}
/* 轮播图上一张和下一张切换的按钮 */
.box > .bannerBox > .skip {
display: inline-block;
position: absolute;
background-color: #ccc;
color: white;
opacity: 0.2;
top: 140px;
width: 40px;
height: 70px;
line-height: 70px;
text-align: center;
font-size: 4rem;
}
.box > .bannerBox > .skip.prev {
left: 0px;
}
.box > .bannerBox > .skip.next {
right: 0px;
}
.box > .bannerBox > .skip:hover {
cursor: pointer;
opacity: 0.5;
color: black;
}
/* 选项卡 */
.tabCard {
margin-top: 10px;
border: 1px solid #ccc;
border-radius: 5px;
width: 400px;
height: 300px;
text-align: center;
}
/* 选项卡和图片懒加载 */
.main {
display: flex;
flex-flow: row nowrap;
}
/* 选项卡头部 */
.tabCard > .tab {
display: flex;
flex-flow: row nowrap;
}
.tabCard > .tab > div:hover {
cursor: pointer;
}
.tabCard > .tab > div {
background-color: white;
border: 1px solid #ccc;
border-radius: 5px;
margin: 3px 3px;
padding: 5px 0px;
width: 95px;
height: 37px;
font-size: 1.5rem;
font-weight: bolder;
}
.tabCard > .tab > div.active {
background-color: #313c46;
color: white;
}
/* 选项卡内容 */
.tabCard > .item {
text-align: left;
display: none;
}
.tabCard > .item > div {
margin-left: 10px;
margin-top: 10px;
font-size: 1.4rem;
}
.tabCard > .item.active {
display: block;
}
/* 图片延时加载 */
.main > .imgBox {
height: 300px;
/* 添加滚动条 */
overflow: auto;
display: grid;
gap: 10px;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.main > .imgBox > img {
width: 100%;
}
/* 评论区 */
.commentBox {
min-height: 300px;
margin-bottom: 20px;
margin-top: 10px;
}
.commentBox > .comm {
margin-top: 10px;
display: flex;
flex-flow: column nowrap;
justify-content: space-evenly;
align-items: center;
}
.commentBox > .comm > .item {
width: 100%;
margin: 5px 0px;
height: 50px;
border: 1px solid #ccc;
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
}
.commentBox > .comm > .item > button {
height: 30px;
width: 100px;
}
var imgs = document.querySelectorAll("img");
var pointList = document.querySelector(".pointList");
//动态给每张图片生成一个小圆点
imgs.forEach(function (img, index) {
var span = document.createElement("span");
//默认显示的是第一张图片
if (index === 0) {
// classList对象是给标签添加类样式
span.classList.add("point", "active");
}
span.classList.add("point");
// dataset对象给标签添加“data-变量名”属性,访问“标签.dataset.变量名”
span.dataset.index = img.dataset.index;
pointList.appendChild(span);
});
//获取所有的小圆点
var points = document.querySelectorAll(".point");
// 为每一个小圆点添加click事件,使用事件冒泡,只需要给它们的父元素添加click事件即可
//addEventListener添加事件监听,第一个参数是事件名称,第2个参数是回调函数,第3个参数是false是冒泡方式
pointList.addEventListener(
"click",
function (ev) {
//ev.target是当前哪个元素发生了click事件,console.log(ev.target);
//ev.currentTarget当前监听的是哪个元素,是div class='pointList'
currentSpan = ev.target;
//判断是不是点击在小圆点之外的pointList的地方,如果点的不是小圆点,则不改变属性样式
if (currentSpan !== ev.currentTarget) {
imgs.forEach(function (img) {
//1.每个图片的active类样式先清除
img.classList.remove("active");
//2.如果当前图片的data-index属性与点击的小圆点的data-index属性相同,则给图片添加active类属性
if (img.dataset.index === currentSpan.dataset.index) {
img.classList.add("active");
setPointActive(currentSpan);
}
});
}
},
false
);
//设置当前被点击的小圆点为高亮
function setPointActive(ele) {
points.forEach(function (point) {
//先清除所有小圆点的高亮,也就是active属性
point.classList.remove("active");
//如果当前小圆点的index值===被点击的小圆点的index值,则当前小圆点设置为高亮,也就是添加active属性
if (point.dataset.index === ele.dataset.index) {
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) {
//获取当前显示的图片
var currentImg = null;
//获取当前点击的是哪个按钮,是前一页,还是下一页
var currentSkip = ev.target;
imgs.forEach(function (img) {
//如果当前图片有类属性active,就是当前显示的图片,获取这张图片
if (img.classList.contains("active")) {
currentImg = img;
}
});
//当点击前一页按钮
if (currentSkip.classList.contains("prev")) {
//清除当前图片的active样式
currentImg.classList.remove("active");
//previousElementSibling获取当前元素的上一个元素,也就是获取上张图片,然后设置active样式
currentImg = currentImg.previousElementSibling;
//如果上一张图片不存在,则设置当前图片为最后一张图片,形成一个循环
if (currentImg !== null && currentImg.nodeName === "IMG") {
currentImg.classList.add("active");
} else {
currentImg = imgs.item(imgs.length - 1);
currentImg.classList.add("active");
}
setPointActive(currentImg);
}
//当点击下一页按钮
if (currentSkip.classList.contains("next")) {
//清除当前图片的active样式
currentImg.classList.remove("active");
//nextElementSibling获取当前元素的下一个元素,也就是获取下一张图片,然后设置active样式
currentImg = currentImg.nextElementSibling;
//如果下一张图片不存在,则设置当前图片为第一张图片,形成一个循环
if (currentImg !== null && currentImg.nodeName === "IMG") {
currentImg.classList.add("active");
} else {
currentImg = imgs.item(0);
currentImg.classList.add("active");
}
setPointActive(currentImg);
}
}
//先获取整个轮播图
var bannerBox = document.querySelector(".bannerBox");
//设置一个定时器
var timer = null;
//当鼠标移出轮播时,设置定时器,每2秒做一个事件派发,模拟点击下一页按钮
bannerBox.addEventListener("mouseout", timerStart, false);
//当鼠标移入轮播时,清除定时器
bannerBox.addEventListener("mouseover", timerEnd, false);
function timerStart() {
var click = new Event("click");
//setInterval设置定时器,每2秒点击一下下一页按钮
timer = setInterval(function () {
//给下一页按钮做一个事件派发,就是模拟点击一页按钮
skip.item(1).dispatchEvent(click);
}, 2000);
}
//clearInterval(),清除定时器
function timerEnd() {
clearInterval(timer);
}
//当页面第一次加载时,启动定时器
timerStart();
var commBtn = document.querySelector(".commentBox>button");
var commText = document.querySelector(".commentBox>textarea");
var comm = document.querySelector(".commentBox>.comm");
commBtn.addEventListener(
"click",
function () {
var textValue = commText.value; //评论内容
var div = document.createElement("div");
div.classList.add("item");
var span = document.createElement("span");
span.innerText = textValue;
var btn = document.createElement("button");
btn.innerText = "删除";
btn.addEventListener(
"click",
function (ev) {
if (confirm("是否删除该评论?")) {
ev.target.parentNode.parentNode.removeChild(ev.target.parentNode);
}
},
false
);
div.appendChild(span);
div.appendChild(btn);
if (comm.childElementCount === 0) {
comm.appendChild(div);
} else {
comm.insertBefore(div, comm.firstElementChild);
}
commText.value = "";
},
false
);
//获取图片容器imgbox
var imgBox = document.querySelector(".imgBox");
//获取所有图片
var boxImages = document.querySelectorAll(".imgBox img");
//图片所在的div的可视高度
var clientHeight = imgBox.clientHeight;
imgBox.addEventListener(
"scroll",
function () {
lazyLoad(boxImages, clientHeight);
},
false
);
function lazyLoad(boxImages, clientHeight) {
var scrollTop = imgBox.scrollTop;
boxImages.forEach(function (img) {
if (img.offsetTop <= clientHeight + scrollTop) img.src = img.dataset.src;
});
}
var tabs = document.querySelector(".tab");
var items = document.querySelectorAll(".item");
tabs.addEventListener("click", showItem, false);
function showItem(ev) {
//点击的是选项卡图标,显示切换
var currentTab = ev.target;
if (ev.target !== ev.currentTarget) {
//遍历tabs的子结点,就是每个tab选项卡
tabs.childNodes.forEach(function (tab) {
//确定选择的是DIV选项卡
if (tab.nodeName === "DIV") {
//清除选项卡的active类样式
tab.classList.remove("active");
}
});
currentTab.classList.add("active");
//遍历选项卡内容的div
items.forEach(function (item) {
//先清除内容上的active的类样式
item.classList.remove("active");
//如果当前点击的选项卡的data-food-index中的内容等于内容中的data-food-index,则内容显示
if (currentTab.dataset.foodIndex === item.dataset.foodIndex) {
item.classList.add("active");
}
});
}
}