批改状态:合格
老师批语:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>classList</title><style>.red {color:red;}.bg {background-color: yellow;}.green{color:green;}</style></head><body><!-- <p class="red bg">欢迎</p> --><p>欢迎</p><script>const p =document.querySelector("p");// p.className='red';// p.className='red bg';// classList:用来动态的设置元素的类样式//对象有属性和方法// p.classList.add("red");// p.classList.add("bg")// p.classList.remove("bg");// p.classList.add("green","bg");// p.classList.replace("green","red");//toggle()动态切换:如果样式表有red 就移除,没有就添加p.classList.toggle("red");</script></body></html>
<!-- id:预定义属性 --><!-- email:自定义属性 --><p id='aaa' data-email='a@php.cn' data-my-age='40' data-index="1">我的资料</p><script>const p = document.querySelector("p");//使用getAttribute()方法获取自定义属性// const email = p.getAttribute("email");// console.log(email);// dataset:读写自定义属性,但是这个属性在HTML中必须使用 'data-' 为前缀// js代码中data- 前缀必须省;之后还有连接线时,连接线必须省去,原连接线后的首字母必须大写console.log(p.dataset.email);console.log(p.dataset.myAge);console.log(p.dataset.index);</script>
知识点:
数组的遍历: forEach()
数组的筛选: filter()
classList属性:classList.remove(),classList.add()
<!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;}.tabs {width: 300px;height: 300px;margin: 30px;background-color: #e6e6e6;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: #e6e6e6;}.tab li:hover {cursor: pointer;}.item{padding: 20px;display: none;}.item.active {display: block;}</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><!-- details --><ul data-index="1" class="item active" ><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></ul><ul data-index="3" class="item"><li><a href="">国际国际国际国际国际国际</a></li><li><a href="">国际国际国际国际国际</a></li><li><a href="">国际国际国际国际</a></li></ul></div><script>const tab = document.querySelector(".tab");const items = document.querySelectorAll(".item");//1. 清空之前所有出于激活状态的选项卡,并将当前点击对象激活tab.onclick = (ev) => {// 事件绑定对象// console.log(ev.currentTarget);//事件触发对象// console.log(ev.target);[...tab.children].forEach((item) => item.classList.remove("active"));ev.target.classList.add("active");//2. 根据自定义属性data-index找到对应的列表并显示//NodeList对象内置了forEach接口items.forEach(item => item.classList.remove("active"));console.log(ev.target);[...items].filter(item => item.dataset.index === ev.target.dataset.index)[0].classList.add("active");};</script></body></html>
知识点:
动态修改 body.style.backgroundImage 值
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>一键换肤</title><style>.container {width: 300px;display: grid;grid-template-columns: repeat(3,1fr);column-gap:10px;}.container>img{width: 100%;border:3px solid #fff;opacity: 0.6;}.container > img:active {opacity: 1;}.container > img:hover {opacity: 1;cursor:pointer;width: 105%;}body {background-image: url("static/images/1.jpg");background-repeat: no-repeat;background-size: cover;}</style></head><body><div class="container"><img src="static/images/1.jpg" alt="" /><img src="static/images/2.jpg" alt="" /><img src="static/images/3.jpg" alt="" /></div><script>//事件代理,不需要给每个图片的缩略图添加点击事件,只需要给父元素添加就可以了// document.querySelector(".container").onclick = ev=>document.body.backgroundImage = "url("+ev.target.src+")";const box = document.querySelector(".container");box.onclick = function (ev) {const body = document.body;let imgUrl = "url("+ev.target.src+")";body.style.backgroundImage = imgUrl;}</script></body></html>
懒加载原理
先将图片的url地址存到自定义属性 data-src 中,当图片top值<视口+滚动高度时 用 data-src 替换 src值img.offsetTop < clientHeight + document.documentElement.scrollTop
知识点:setTimeout(),两个事件 scroll,load
//视口高度let viewHeight = document.documentElement.clientHeight;//滚动高度document.onscroll = ev=>{console.log(document.documentElement.scrollTop);}
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>图片懒加载</title><style>.container {width: 500px;display: grid;gap: 10px;grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));}.container img {width: 100%;}</style></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-9.jpg" /><img src="images/temp.jpg" alt="" data-src="images/img-10.jpg" /></div><script>// const imgs =document.images;const images = document.querySelectorAll(".container img");const clientHeight = document.documentElement.clientHeight;window.addEventListener("scroll", layzyload);window.addEventListener("load", layzyload);function layzyload() {images.forEach((img) => {if (img.offsetTop < clientHeight + document.documentElement.scrollTop)setTimeout(() => (img.src = img.dataset.src), 500);});}// images</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.querySelectorAll(".container > .skip > a");// 创建出一组与图片数量一致的小按钮function autoCreateBtns(ele, imgCount) {const frag = document.createDocumentFragment();for (let i = 0; i < imgCount; 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)));let iMax = imgs.length;//上一张let prevSkip = document.querySelector(".prev");prevSkip.addEventListener("click", () => {let iIndex = getActiveEle(imgs).dataset.index;let iPrev = parseInt(iIndex) - 1;iPrev < 1? setActiveEle(iMax.toString()): setActiveEle(iPrev.toString());});//下一张let nextSkip = document.querySelector(".next");nextSkip.addEventListener("click", () => {let iIndex = getActiveEle(imgs).dataset.index;let iNext = parseInt(iIndex) + 1;iNext > iMax? setActiveEle("1"): setActiveEle(iNext.toString());});//事件派发startInterval = function () {const ev = new Event("click");nextSkip.dispatchEvent(ev);};//使用间歇式定时器let intervalID = setInterval(startInterval, 2000);let container = document.querySelector(".container");container.addEventListener("mouseover", () => clearInterval(intervalID));container.addEventListener("mouseleave",() => (intervalID = setInterval(startInterval, 2000)));</script></body></html>
小结:调试过程中因为没有将事件派发封装,直接使用 setInterval() 设置派发造成一直无法达到效果。
由于没有了解setInterval用法造成时间的浪费,吃一堑长一智吧。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号