批改状态:合格
老师批语:
//css样式<style>* {margin: 0;padding: 0;box-sizing: border-box;}a {text-decoration: none;color: #333;}ul li {list-style: none;}.con {width: 20em;box-shadow: 0 0 3px #ccc;margin: 2em;}.con .tab {display: grid;grid-template-columns: repeat(3, 1fr);text-align: center;background-color: #ccc;}.con .tab li {padding: 0.5em 0;cursor: pointer;}.con .active {background-color: #fff;}.con .item {padding: 0.5em;}.con .item li {padding: 0.2em 0;}.item {padding: 20px;display: none;}.item.active {display: block;}</style>//html代码<div class="con"><ul class="tab"><li class="active" data-index="1">第一个</li><li data-index="2">第二个</li><li data-index="3">第三个</li></ul><ul data-index="1" class="item 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><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="item"><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><li><a href="#">第二个选项卡内容</a></li><li><a href="#">第二个选项卡内容</a></li><li><a href="#">第二个选项卡内容</a></li><li><a href="#">第二个选项卡内容</a></li></ul><ul data-index="3" class="item"><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><li><a href="#">第三个选项卡内容</a></li><li><a href="#">第三个选项卡内容</a></li><li><a href="#">第三个选项卡内容</a></li><li><a href="#">第三个选项卡内容</a></li></ul></div>//js代码<script>const tab = document.querySelector(".con .tab");const items = document.querySelectorAll(".con .item");tab.onmouseover = (ev) => {[...tab.children].forEach((item) => item.classList.remove("active"));console.log([Array.from(tab.children)]);ev.target.classList.add("active");items.forEach((item) => item.classList.remove("active"));[...items].filter((item) => item.dataset.index === ev.target.dataset.index)[0].classList.add("active");};</script>

//html代码<ul class="imgs"><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" /></ul>//js代码<script>//获取图片列表const imgs = document.querySelectorAll(".imgs img");//获取当前视口高度const clientHeight = document.documentElement.clientHeight;window.addEventListener("scroll", layzyload);window.addEventListener("load", layzyload);function layzyload() {//获取滚动高度let scrollTop = document.documentElement.scrollTop;//遍历当前图片是否到了可视区 图片到顶部的高度小于视口+滚动高度,即认为图片进入可视区imgs.forEach((img) => {if (img.offsetTop < scrollTop + clientHeight) {setTimeout(() => (img.src = img.dataset.src), 500);}});}</script>
//html代码<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"><!-- 这些小按钮应该是js根据图片数量动态来创建 --></nav><!-- 3. 翻页按钮(只有二个,分别在左右) --><nav class="skip"><!-- <: 实体符号 --><a href="#" class="prev"><</a><a href="#" class="next">></a></nav></div>//JS代码<script>// 获取相关的元素对象// 图片组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");// #: 防止默认行为,更加规范用 ev.preventDefault();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 > *");// 下面声明2个公共函数// 1. 获取激活的元素function getActiveEle(eles) {let activities = Array.from(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),false));// 作业1: 为每个翻页按钮添加事件完成图片翻页(兄弟节点的处理)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);}}// 作业2: 图片每隔2秒自动播放(定时器,事件自动派发)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);}</script>
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号