批改状态:合格
老师批语:
<div class="container"><div class="img-group"></div><!-- 2. 和图片数量对应的小按钮 --><div class="btn-group"></div><!-- 3. 向前和向后的翻页按钮 --><div class="skip"><a class="prev" href="" onclick="prevImg(event)"><</a><a class="next" href="" onclick="nextImg(event)">></a></div></div><ul class="list"></ul>
加入入css效果
/* 初始化 */* {margin: 0;padding: 0;box-sizing: border-box;}a {text-decoration: none;}/* 轮播图的容器 */.container {width: 62.5em;height: 22em;margin: 1em auto;/* 转为定位元素/定位父级 */position: relative;}.container:hover {cursor: pointer;}/* 图片组 */.container > .img-group img {width: 100%;height: 100%;border-radius: 0.6em;/* 默认全部隐藏 */display: none;/* 将所有的图片进行绝对定位,确保每一次只看到一张,所有图片共享这个容器 */position: absolute;left: 0;top: 0;}/* 设置默认显示的图片(第一张) */.container > .img-group img.active {display: block;}/* 按钮组(独立按钮) */.container > .btn-group {position: absolute;left: 0;right: 0;bottom: 0;/* 水平居中 */text-align: center;}.container > .btn-group span {/* 转成行内块元素: 即能水平排列,双支持宽度设置 */display: inline-block;padding: 0.5em;margin: 0 0.2em;background-color: #fff;border-radius: 50%;}.container > .btn-group span:hover {cursor: pointer;}.container > .btn-group .active {background-color: #000;}/* 翻页按钮 */.container .skip a {position: absolute;width: 2.5rem;height: 5rem;line-height: 5rem;text-align: center;opacity: 0.3;top: 9rem;font-weight: lighter;font-size: 2rem;background-color: #ccc;}.container .skip .prev {left: 0;}.container .skip .next {right: 0;}.container .skip *:hover {opacity: 0.6;color: #666;}
<script>// 文档片断// const ul = document.querySelector(".list");// // 文档片断 ,就是临时的父节点// const frag = document.createDocumentFragment();// for (let i = 0; i < 100; i++) {// const li = document.createElement("li");// li.textContent = "item" + (i + 1);// // 这个添加操作,是在内存中进行,与页面无关// frag.append(li);// }// ul.append(frag);const banners = ["imges2/1banner.jpg","imges2/2banner.jpg","imges2/3banner.jpg","imges2/4banner.jpg",];// 图片组元素const imgGroup = document.querySelector(".container > .img-group");// 按钮组const btnGroup = document.querySelector(".container > .btn-group");// 当页面加载成功,将所有图片和与图片对应的小按钮全部渲染出来window.onload = () => {// 1. 生成所有图片createImgs(imgGroup, banners.length);// 2. 生成与图片对应的小按钮createBtns(btnGroup, banners.length);};
生成图片
// 生成图片function createImgs(parent, length) {const frag = document.createDocumentFragment();for (let i = 0; i < length; i++) {const img = document.createElement("img");img.src = banners[i];// 为每一张图片添加一个索引: data-index,它与对应的小按钮一一对应img.dataset.index = `${i + 1}`;if (i === 0) img.classList.add("active");// 使用文档片断,在内存中添加frag.append(img);}parent.append(frag);}// 生成按钮function createBtns(parent, length) {const frag = document.createDocumentFragment();for (let i = 0; i < length; i++) {const span = document.createElement("span");// 为每一张图片添加一个索引: data-index,它与对应的小按钮一一对应span.dataset.index = `${i + 1}`;if (i === 0) span.classList.add("active");// 为新生成按钮添加点击事件span.onclick = showImgs;// 使用文档片断,在内存中添加frag.append(span);}parent.append(frag);}// parent.append(frag);// 为这个按钮的showImgs创建函数function showImgs(ev) {// 1. 获取所有图片和按钮const imgArr = imgGroup.querySelectorAll("img");const btnArr = btnGroup.querySelectorAll("span");console.log(imgArr, btnArr);// 2. 根据按钮激活状态设置对应的图片显示btnArr.forEach((btn) => btn.classList.remove("active"));ev.target.classList.add("active");imgArr.forEach((img) => img.classList.remove("active"));// 3. 根据按钮与图片的data-index属性的值,匹配上再激活imgArr.forEach((img) => {if (ev.target.dataset.index === img.dataset.index)img.classList.add("active");});}// 翻页// 向前function prevImg(ev) {// 禁用<a>标签默认跳转行为,当按钮用ev.preventDefault();// 1. 当前图片和当前的按钮const currentImg = imgGroup.querySelector("img.active");const currentBtn = btnGroup.querySelector("span.active");console.log(currentImg, currentBtn);// 2. 取消当前图片和当前的按钮激活状态currentImg.classList.remove("active");currentBtn.classList.remove("active");// 3. 取到当前图片和按钮的前一个兄弟节点const prevImg = currentImg.previousElementSibling;const prevBtn = currentBtn.previousElementSibling;// 4. 如果存在前一个兄弟,就设置它为激活并显示出来if (prevImg !== null && prevBtn !== null) {prevBtn.classList.add("active");prevImg.classList.add("active");} else {imgGroup.lastElementChild.classList.add("active");btnGroup.lastElementChild.classList.add("active");}}// 向后function nextImg(ev) {// 禁用<a>标签默认跳转行为,当按钮用ev.preventDefault();// 1. 当前图片和当前的按钮const currentImg = imgGroup.querySelector("img.active");const currentBtn = btnGroup.querySelector("span.active");console.log(currentImg, currentBtn);// 2. 取消当前图片和当前的按钮激活状态currentImg.classList.remove("active");currentBtn.classList.remove("active");// 3. 取到当前图片和按钮的前一个兄弟节点const nextImg = currentImg.nextElementSibling;const nextBtn = currentBtn.nextElementSibling;// 4. 如果存在前一个兄弟,就设置它为激活并显示出来if (nextImg !== null && nextBtn !== null) {nextBtn.classList.add("active");nextImg.classList.add("active");} else {imgGroup.firstElementChild.classList.add("active");btnGroup.firstElementChild.classList.add("active");}}
作业:每2s自送切换到下一个,使用setInterval 执行间歇事件
setInterval(() => {//1、当前图片和当前按钮const currentImg = imgGroup.querySelector("img.active");const currentBtn = btnGroup.querySelector("span.active");//2、取消当前图片和当前按钮的激活状态currentImg.classList.remove("active");currentBtn.classList.remove("active");//3、取得当前图片和按钮的前一个兄弟节点const nextImg = currentImg.nextElementSibling;const nextBtn = currentBtn.nextElementSibling;////4、如果存在前一个兄弟,就设置它为激活状态if (nextImg !== null && nextBtn !== null) {nextBtn.classList.add("active");nextImg.classList.add("active");} else {imgGroup.firstElementChild.classList.add("active");btnGroup.firstElementChild.classList.add("active");}}, 2000);
全选复选框
const checkAll = document.querySelector("#check-all");const checkItems = document.getElementsByName("item");// change: 当控件中的值发生变化时触发// 将全选按钮的状态,赋值给下面所有的商品的checkboxcheckAll.onchange = function (ev) {checkItems.forEach(function (item) {item.checked = ev.target.checked;});};checkItems.forEach(function (item) {// onchange监测它的状态item.onchange = function () {//只有全部选中才更新全选按钮的状态checkAll.checked = [...checkItems].every(function (item) {return item.checked;});};});// 一个点掉就会取消全选,全部点上全选就会自动选上
自动计算
所有的计算,都是基于数量的变化
const numInput = document.querySelectorAll('input[type="number"]');numInput.forEach(function (input) {input.onchange = autoCalculate;});function autoCalculate() {// 1. 获取每个商品的金额: 数量 * 单价const numbers = document.querySelectorAll('input[type="number"]');const numArr = [...numbers].map(function (num) {return num.value * 1;});const prices = document.querySelectorAll("tbody .price");const priceArr = [...prices].map(function (num) {return num.textContent * 1;});// 2. 计算出每个商品的金额(数组)const amountArr = [priceArr, numArr].reduce(function (prev, curr) {return prev.map(function (item, key) {return item * curr[key];});});console.log(amountArr);
总金额
let total = amountArr.reduce(function (prev, curr) {return prev + curr;});
总数量
let sum = numArr.reduce(function (prev, curr) {return prev + curr;});let total = amountArr.reduce(function (prev, curr, index) {if (index == 1) {if (!checkItems[0].checked) prev = 0;}if (checkItems[index].checked) {return prev + curr;} else {return prev;}});
选择去掉商品自动计算
第一和第二句checkAll.onchange里加上一个autoCalculate()即7和13行。最后一句在计算的函数里,添加一条判断语句,判断前面的check如果没勾上,就不纳入计算(下列代码的24行)
// change: 当控件中的值发生变化时触发// 将全选按钮的状态,赋值给下面所有的商品的checkboxcheckAll.onchange = function (ev) {checkItems.forEach(function (item) {item.checked = ev.target.checked;});// autoCalculate();};checkItems.forEach(function (item) {// onchange监测它的状态item.onchange = function (ev) {//autoCalculate();//只有全部选中才更新全选按钮的状态checkAll.checked = [...checkItems].every(function (item) {return item.checked;});};});// 1. 获取每个商品的金额: 数量 * 单价const numbers = document.querySelectorAll('input[type="number"]');const numArr = [...numbers].map(function (num) {//if (!num.parentNode.parentNode.getElementsByClassName("item")[0].checked)return 0;return num.value * 1;});
将所有数据渲染到页面中
document.querySelectorAll(".amount").forEach(function (item, index) {item.textContent = amountArr[index];});document.querySelector("#total-amount").textContent = total;document.querySelector("#sum").textContent = sum;}window.onload = autoCalculate;
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号