标签切换、图片墙调整、轮播图及购物车小案例相关知识总结
标签切换
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>选项卡</title>
</head>
<body>
<div class="tabs">
<!-- 导航 -->
<!-- <ul class="tab" onclick="show(event)"> -->
<ul class="tab" onmouseover="show(event)">
<!-- data-index: 自定义属性,用dataset来读写 -->
<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>
</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>
</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>
</ul>
</div>
<script>
//数组.filter()数组过滤器
let arr = [3, 4, 5, 72, 35, 7, 8, 95, 5, 7, 8, 34, 10];
//filter前面加数组,括号内是箭头函数
let res = arr.filter((item) => item >= 5);
console.log(res);
//给上导航绑定点击事件
//函数的形参跟实参是事件
function show(ev) {
//获取事件绑定者
console.log(ev.currentTarget);
//获取事件触发者
console.log(ev.target);
//赋值给变量
const ul = ev.currentTarget;
const li = ev.target;
//循环遍历li,取消之前已经添加的active
// const lis = document.querySelectorAll(".tabs>.tab>li");
// for (let i = 0; i < lis.length; i++) {
// if (lis[i].className === "active") {
// lis[i].classList.remove("active");
// }
// }
[...ul.children].forEach((item) => item.classList.remove("active"));
//给li动态添加class类
li.classList.add("active");
const uls = [...document.querySelectorAll(".tabs>.item")];
uls.forEach((item) => item.classList.remove("active"));
//这里获取的还是数组,后面加个索引0
uls.filter((item) => item.dataset.index === li.dataset.index)[0].classList.add("active");
}
</script>
</body>
</html>
图片墙调整
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>在线相册</title>
</head>
<body>
<ul class="container"></ul>
<script>
//array.reduce():数组的归并函数
//array.reduce(function(起始值(如果不自定义起始值,则默认是数组的第一个值),起始值的下一个值){},起始值(可以是任意值));
// let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
// arr.reduce(function (prev, cur) {
// console.log(prev, cur);
// return prev + cur;
// }, 11);
let imgS = [
"images/img_1.jpg",
"images/img_2.jpg",
"images/img_3.jpg",
"images/img_4.jpg",
"images/img_5.jpg",
"images/img_6.jpg",
"images/img_7.jpg",
"images/img_8.jpg",
];
const ul = document.querySelector(".container");
window.onload = showImages();
function showImages() {
let res = imgS.reduce(function (prev, cur) {
let tpl = `
<li>
<img src="${cur}"/>
<div>
<button onclick=prev(this.parentNode.parentNode)>向前</button>
<button onclick=next(this.parentNode.parentNode)>向后</button>
<button onclick=del(this.parentNode.parentNode)>删除</button>
</div>
</li>
`;
return prev + tpl;
//前面得加个空字符串,要不默认数组是第一个开始,这里添加的却是当前,会导致第一个没有li跟img标签的
}, "");
// console.log(res);
ul.insertAdjacentHTML("afterbegin", res);
}
//confirm()弹出对话框确认为真取消为假
function del(ele) {
return confirm("你要毁掉我的老婆??") ? ele.remove() : false;
}
//parent.insertBefore(要插入的子元素,插入的子元素的位置),insertBefore前面必须是父元素
// previousSibling 属性返回元素节点之前的兄弟节点(包括文本节点、注释节点);
// previousElementSibling 属性只返回元素节点之前的兄弟元素节点(不包括文本节点、注释节点);
function prev(ele) {
let prevNode = ele.previousElementSibling;
if (prevNode === null) {
alert("已经是大老婆了");
return false;
} else {
ul.insertBefore(ele, prevNode);
}
}
function next(ele) {
let nextNode = ele.nextElementSibling;
if (nextNode === null) {
alert("已经打入冷宫了");
return false;
} else {
ul.insertBefore(nextNode, ele);
}
}
</script>
</body>
</html>
轮播图
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>轮播图</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<!-- 容器区域 -->
<div class="container">
<!-- 图片组 -->
<div class="img-group"></div>
<!-- 翻页组 -->
<div class="skip">
<a class="prev" href="" onclick="prevImg(event)"><</a>
<!-- 禁用a标签默认行为方法1 -->
<!-- <a class="prev" href="javascript:;" onclick="prevImg(event)"><</a> -->
<a class="next" href="" onclick="nextImg(event)">></a>
</div>
<!-- 按钮组 -->
<div class="btn-group"></div>
</div>
<script>
//图片
const images = ["images/banner_1.jpg", "images/banner_2.jpg", "images/banner_3.jpg", "images/banner_4.jpg"];
const imgGroup = document.querySelector(".img-group");
//按钮
const btnGroup = document.querySelector(".btn-group");
window.onload = () => {
createImages(imgGroup, images.length);
createBtns(btnGroup, images.length);
//页面加载完成后自动调用一次自动循环
autoStart(event);
};
function createImages(parent, length) {
//创建虚拟节点对象,减少页面渲染抖动
const frag = document.createDocumentFragment();
for (let i = 0; i < length; i++) {
//这个img必须在for循环里面,这样才能每次都生成一个img,放到外面只能每次都更新里面的属性
const img = document.createElement("img");
img.src = images[i];
img.alt = `banner${i + 1}`;
img.dataset.index = `${i + 1}`;
if (i === 0) img.classList.add("active");
frag.append(img);
}
//将虚拟节点对象的子孙节点全部插入到parent中
parent.append(frag);
}
function createBtns(parent, length) {
//创建虚拟节点对象,减少页面渲染抖动
const frag = document.createDocumentFragment();
for (let i = 0; i < length; i++) {
const span = document.createElement("span");
span.dataset.index = `${i + 1}`;
// 给span按钮添加点击事件
if (i === 0) span.classList.add("active");
//这里跟html中不同 changeImg后面不需要加括号
//加上括号是执行的意思,添加事件的回调函数应该就是给相应的事件属性赋值,而很明显需要把一个函数赋值给这个事件属性,
//而不是函数的调用结果。所以在js中的绑定是直接赋值。而在标签内的事件属性的值是由引号包裹的,代表的是当点击该元素时,执行引号内的代码,直接把引号内的代码拿出来跑,如果你不加括号,那就不会调用那个函数。
span.onclick = changeImg;
frag.append(span);
}
//
//将虚拟节点对象的子孙节点全部插入到parent中
parent.append(frag);
}
//图片切页小按钮
function changeImg(ev) {
const span = btnGroup.querySelectorAll("span");
const img = imgGroup.querySelectorAll("img");
// console.log(img);
// console.log(ev.target);
// for (let i = 0; i < img.length; i++) {
// span[i].classList.remove("active");
// img[i].classList.remove("active");
// }
// forEach简写
[span, img].forEach((items) => {
//二次遍历
items.forEach((item) => {
//判断带active的取消,不带的不管
if (item.classList.contains("active")) item.classList.remove("active");
});
});
ev.target.classList.add("active");
img.forEach((item) => {
if (item.dataset.index === ev.target.dataset.index) item.classList.add("active");
});
}
//前翻页
function prevImg(ev) {
// 禁用a标签默认行为方法二
ev.preventDefault();
//拿到当前带active类的按钮跟图片
const span = btnGroup.querySelector("span.active");
const img = imgGroup.querySelector("img.active");
//拿到当前带active类的按钮跟图片的对应的前一个兄弟元素
const spanPrev = span.previousElementSibling;
const imgPrev = img.previousElementSibling;
span.classList.remove("active");
img.classList.remove("active");
if (spanPrev !== null && imgPrev !== null) {
spanPrev.classList.add("active");
imgPrev.classList.add("active");
} else {
btnGroup.lastElementChild.classList.add("active");
imgGroup.lastElementChild.classList.add("active");
}
}
//后翻页
function nextImg(ev) {
// 禁用a标签默认行为方法二
ev.preventDefault();
//拿到当前带active类的按钮跟图片
const span = btnGroup.querySelector("span.active");
const img = imgGroup.querySelector("img.active");
//拿到当前带active类的按钮跟图片的对应的前一个兄弟元素
const spanNext = span.nextElementSibling;
const imgNext = img.nextElementSibling;
span.classList.remove("active");
img.classList.remove("active");
if (spanNext !== null && imgNext !== null) {
spanNext.classList.add("active");
imgNext.classList.add("active");
} else {
btnGroup.firstElementChild.classList.add("active");
imgGroup.firstElementChild.classList.add("active");
}
}
// 初步自动播放
// const next = document.querySelector(".container>.skip>.next");
// const autoClick = new Event("click");
// setInterval(() => next.dispatchEvent(autoClick), 2000);
//加入限制,这里需要注意setInterval()如果需要停止,那么得把它赋值给一个变量,到时候停止这个同名变量
let time = null;
const next = document.querySelector(".container>.skip>.next");
const container = document.querySelector(".container");
const autoClick = new Event("click");
container.addEventListener("mouseover", autoStop);
container.addEventListener("mouseout", autoStart);
// container.onmouseover = autoStop;
// container.onmouseout = autoStart;
function autoStart() {
time = setInterval(() => next.dispatchEvent(autoClick), 2000);
}
function autoStop() {
clearInterval(time);
}
</script>
</body>
</html>
购物车
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>购物车</title>
</head>
<body>
<table>
<caption>
我的购物车
</caption>
<thead>
<th><input type="checkbox" name="checkAll" id="check-all" checked /><label for="check-all">全选</label></th>
<th>图片</th>
<th>品名</th>
<th>单位</th>
<th>单价/元</th>
<th>数量</th>
<th>金额/元</th>
</thead>
<tbody>
<tr>
<td>
<input type="checkbox" name="item" class="item" value="SN-1020" checked />
</td>
<td>
<a href=""><img src="images/p1.png" alt="" /></a>
</td>
<td>JavaScript权威指南(第七版)</td>
<td>本</td>
<td class="price">100</td>
<td>
<input type="number" min="1" value="1" />
</td>
<td class="amount">0</td>
</tr>
<tr>
<td>
<input type="checkbox" name="item" class="item" value="SN-1020" checked />
</td>
<td>
<a href=""><img src="images/p2.png" alt="" /></a>
</td>
<td>JavaScript高级程序设计(第四版)</td>
<td>本</td>
<td class="price">129</td>
<td>
<input type="number" min="1" value="1" />
</td>
<td class="amount">0</td>
</tr>
<tr>
<td>
<input type="checkbox" name="item" class="item" value="SN-1030" checked />
</td>
<td>
<a href=""><img src="images/p3.png" alt="" /></a>
</td>
<td>JavaScript忍者秘籍(第二版)</td>
<td>台</td>
<td class="price">99</td>
<td>
<input type="number" min="1" value="1" />
</td>
<td class="amount">0</td>
</tr>
<tr>
<td>
<input type="checkbox" name="item" class="item" value="SN-1040" checked />
</td>
<td>
<a href=""><img src="images/p4.png" alt="" /></a>
</td>
<td>ThinkPad X1 Carbon 2021</td>
<td>台</td>
<td class="price">12999</td>
<td>
<input type="number" min="1" value="1" />
</td>
<td class="amount">0</td>
</tr>
<tr>
<td>
<input type="checkbox" name="item" class="item" value="SN-1050" checked />
</td>
<td>
<a href=""><img src="images/p5.png" alt="" /></a>
</td>
<td>MacBook Pro 16 10代i7 16G 512G</td>
<td>台</td>
<td class="price">23800</td>
<td>
<input type="number" min="1" value="1" />
</td>
<td class="amount">0</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">总计:</td>
<td id="sum">0</td>
<td id="total-amount">0</td>
</tr>
</tfoot>
</table>
<div style="width: 90%; margin: 10px auto">
<button style="float: right; width: 100px">结算</button>
</div>
<script>
// let arr = [3, 4, 5, 6, 7, 8];
// console.log(arr.some((item) => item > 4));
// console.log(arr.every((item) => item > 4));
// onchange
const checkAll = document.getElementById("check-all");
const items = document.getElementsByName("item");
checkAll.onchange = function (ev) {
//首先配置下面商品的选择跟随上面全选按钮进行全选或全不选,下面跟随上面的状态,这里不能设置true,设置true就不管咋点都是全选
items.forEach((item) => (item.checked = ev.target.checked));
};
//配置有一个按钮没选中全选失效,全部选中全选生效
// items.forEach(function (item) {
// item.onchange = function (ev) {
// if ([...items].some((item) => item.checked == false)) {
// checkAll.checked = false;
// } else if ([...items].every((item) => item.checked == true)) {
// checkAll.checked = true;
// }
// };
// });
//不用这么复杂,只需要先遍历一遍下面的小按钮,当小按钮点击的时候触发一个onchange,函数对象中直接用array.every作判断给checkAll的checked属性赋值true or false就可以啊
items.forEach(function (item) {
item.onchange = function () {
checkAll.checked = [...items].every((item) => item.checked);
};
});
//方法一:
// const price = document.querySelectorAll(".price");
// const number = document.querySelectorAll("input[type='number']");
// const amount = document.querySelectorAll(".amount");
// const sum = document.getElementById("sum");
// const totalAmount = document.getElementById("total-amount");
// let myChange = new Event("change");
// for (let i = 0; i < [...price].length; i++) {
// number[i].onchange = getPrice;
// number[i].onkeyup = getPrice;
// number[i].afterpaste = getPrice;
// items[i].onchange = getPrice;
// number[i].dispatchEvent(myChange);
// }
// function getPrice() {
// let s = 0;
// let t = 0;
// for (let i = 0; i < [...price].length; i++) {
// if (number[i].value == "") {
// number[i].value = 0;
// } else {
// if (typeof number[i].value !== "number" || number[i].value % 1 !== 0) number[i].value = parseInt(number[i].value);
// }
// amount[i].innerText = price[i].innerText * number[i].value;
// if (items[i].checked === false) {
// s += 0;
// t += 0;
// } else {
// s += parseInt(number[i].value);
// t += parseInt(amount[i].innerText);
// }
// }
// sum.innerText = s;
// totalAmount.innerText = t;
// }
//方法二:
//获取数量
const number = document.querySelectorAll("input[type='number']");
//给每个数量加监听事件
[items, number].forEach((items) =>
items.forEach((item) => {
item.onchange = getPrice;
item.onkeyup = getPrice;
item.afterpaste = getPrice;
})
);
function getPrice() {
//获取数量
const number = document.querySelectorAll("input[type='number']");
//这里的num是number类型的input元素啊,别忘了加value,用map函数遍历成新的数组,×1使数据类型变为数值
// [...number].forEach((num) => (num.value = parseInt(num.value)));
//数量这里用parseInt()强制转换成了整型
const numArr = [...number].map((num) => (num.value = parseInt(num.value)));
//获取单价
const price = document.querySelectorAll(".price");
const priceArr = [...price].map((price) => (price.textContent = price.textContent * 1));
//遍历出每一个的单条总价(显示用)
const amountArrA = [numArr, priceArr].reduce((prev, cur) => prev.map((val, key) => val * cur[key]));
//遍历item的checked属性做个判断,判断为真时保留数值,为假时数量赋值0
items.forEach((item, key) => {
if (!item.checked) numArr[key] = 0;
});
//遍历出每一个的单条总价(计算用)
const amountArrC = [numArr, priceArr].reduce((prev, cur) => prev.map((val, key) => val * cur[key]));
// console.log(amountArr);
//总数
const nubSum = numArr.reduce((prev, cur) => prev + cur);
//总价
const priceSum = amountArrC.reduce((prev, cur) => prev + cur);
const amount = document.querySelectorAll(".amount");
const sum = document.getElementById("sum");
const totalAmount = document.getElementById("total-amount");
//加入页面
amount.forEach((item, index) => (item.textContent = amountArrA[index]));
sum.textContent = nubSum;
totalAmount.textContent = priceSum;
}
window.onload = function () {
getPrice();
};
</script>
</body>
</html>