一、一键换肤
1.建demo1.html,引入change-skin.css、change-skin.js
<!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="static/css/change-skin.css" />
</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 src="static/js/change-skin.js"></script>
</body>
</html>
2.change-skin.css
.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:hover {
opacity: 1;
cursor: pointer;
width: 105%;
}
body {
background-image: url("../images/1.jpg");
background-repeat: no-repeat;
}
3.change-skin.js
// 将当前图片的src赋值给body的背景
// 事件代理
document.querySelector(".container").addEventListener("click", setSkin, false);
function setSkin(ev) {
// ev.target: 事件触发者(img)
// ev.currentTarget: 事件绑定者(.container)
document.body.style.backgroundImage = "url(" + ev.target.src + ")";
}
二、购物车自动计算,共4个文档
1.demo.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="check.css" />
</head>
<body>
<table>
<caption>
购物车
</caption>
<thead>
<tr>
<th>
<input
type="checkbox"
name="checkAll"
id="check-all"
checked
/><label for="check-all">全选</label>
</th>
<th>ID</th>
<th>品名</th>
<th>单位</th>
<th>单价/元</th>
<th>数量</th>
<th>金额/元</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="checkbox" name="itemId" value="SP-1" />
</td>
<td>SP-1</td>
<td>手机</td>
<td>部</td>
<td>1899</td>
<td>
<input type="number" name="counter" value="1" min="1" step="1" />
</td>
<td></td>
</tr>
<tr>
<td>
<input type="checkbox" name="itemId" value="SP-2" />
</td>
<td>SP-2</td>
<td>电脑</td>
<td>台</td>
<td>4999</td>
<td>
<input type="number" name="counter" value="1" min="1" step="1" />
</td>
<td></td>
</tr>
<tr>
<td>
<input type="checkbox" name="itemId" value="SP-3" />
</td>
<td>SP-3</td>
<td>汽车</td>
<td>台</td>
<td>200000</td>
<td>
<input type="number" name="counter" value="1" min="1" step="1" />
</td>
<td></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" style="font-weight: 700;">总计:</td>
<td id="total-num"></td>
<td id="total-price"></td>
</tr>
</tfoot>
</table>
<div style="width: 90%; margin: 10px auto;">
<button style="float: right; width: 100px;">结算</button>
</div>
</td>
</tr>
</tfoot>
</table>
<script src="select.js"></script>
<script src="calculate.js"></script>
</body>
</html>
2.check.css
table {
border-collapse: collapse;
width: 90%;
text-align: center;
margin: auto;
}
table caption {
margin-bottom: 15px;
font-size: 1.5rem;
}
table th,
table td {
border: 1px solid;
padding: 5px;
}
table thead tr:first-of-type {
background-color: lightblue;
}
/* 隔行变色: 偶数行 */
table tbody tr:nth-of-type(even) {
background-color: lightcyan;
}
table input[type="checkbox"] {
width: 20px;
height: 20px;
}
button {
width: 150px;
height: 30px;
outline: none;
border: none;
background-color: seagreen;
color: white;
letter-spacing: 5px;
}
button:hover {
background-color: coral;
cursor: pointer;
}
3.select.js
/** @format */
var selectAllBtn = document.querySelector("#check-all");
//获取每个选项的复选框
var itemBtns = document.querySelectorAll("input[name=itemId]");
//获取所有单价
prices = document.querySelectorAll("table>tbody>tr>td:nth-of-type(5)");
//获取所有商品的数量
numbers = document.querySelectorAll("table>tbody>tr>td>input[type=number]");
// 获取商品单价数组
var unitprice_array = getArrar(prices, "innerText");
// 获取商品数量数组
var counts = getArrar(numbers, "value");
// 获得所有金额
var sumPrices = document.querySelectorAll("tbody > tr > td:nth-of-type(7)");
//初始化 默认为全选状态
init();
function init() {
selectAllBtn.checked = true;
checkAll();
}
//监听全选按钮状态
selectAllBtn.addEventListener("change", checkAll, false);
//添加状态刷新,当全选按钮状态改变时重新渲染页面
selectAllBtn.addEventListener("change", refresh, false);
function refresh() {
autoCalculate();
}
//设置复选框的取消和选中状态并添加默认值
function checkAll() {
itemBtns.forEach(function (btn) {
btn.checked = selectAllBtn.checked;
if (!selectAllBtn.checked) {
btn.parentNode.parentNode.children[5].children.counter.value = 0;
} else {
btn.parentNode.parentNode.children[5].children.counter.value = 1;
}
});
}
itemBtns.forEach(function (btn) {
btn.addEventListener("change", checkAllStatus, false);
});
function checkAllStatus() {
//获取兄弟节点value值,实现取消选中自动重新计算
item_num = this.parentNode.parentNode.querySelector("td>input[type=number]")
.value;
if (this.checked == false && item_num > 0) {
this.parentNode.parentNode.querySelector("td>input[type=number]").value = 0;
} else {
this.parentNode.parentNode.querySelector("td>input[type=number]").value = 1;
}
changeStatus();
autoCalculate();
}
//设置复选框状态
function changeStatus() {
var num = 0;
itemBtns.forEach(function (btn) {
if (btn.checked == true) {
num++;
}
});
// console.log(num);
selectAllBtn.checked = itemBtns.length == num;
}
//将传入伪数组转换为新的数组
function getArrar(array, attr_name) {
return Array.from(array).map((item) => parseInt(item[attr_name]));
}
//每个项目的金额
var amounts = getAmounts(unitprice_array, counts);
//将每个项目的金额渲染到表格中
let subtotal = document.querySelectorAll("tbody>tr>td:last-of-type");
//forEach的第二个参数为当前item的索引
subtotal.forEach((item, index) => (item.innerText = amounts[index]));
//计算每个项目的金额,返回一个新的数组
function getAmounts(unitprice_array, counts) {
let res = [];
for (var i = 0; i < counts.length; i++) {
let amount = unitprice_array[i] * counts[i];
res.push(amount);
}
return res;
}
//计算总金额并渲染到页面
var totalNum = (document.querySelector("#total-num").innerText = getSum(
counts
));
var totalAmount = (document.querySelector("#total-price").innerText = getSum(
amounts
));
//使用reduce方法计算数组每项的和
function getSum(array) {
return array.reduce((total, num) => total + num, 0);
}
//为数量控件添加change事件
numbers.forEach((item) => item.addEventListener("input", autoCalculate));
numbers.forEach((item) => item.addEventListener("input", autoSelect));
//当input[type=number]值改变时设置复选框选中,重新计算金额
function autoSelect() {
this.parentNode.parentNode.querySelector(
"td>input[name=itemId]"
).checked = true;
// 重新计算所有被选中复选框的数量
changeStatus();
}
//自动计算函数
function autoCalculate() {
counts = getArrar(numbers, "value");
amounts = getAmounts(unitprice_array, counts);
subtotal.forEach((item, index) => (item.innerText = amounts[index]));
totalNum = document.querySelector("#total-num").innerText = getSum(counts);
totalAmount = document.querySelector("#total-price").innerText = getSum(
amounts
);
}
4.calculate.js
// 商品数量: 数组
var counts = [];
// 商品金额: 数组
var amounts = [];
// 商品单价: 数组
var unitPrices = [];
// 商品总数量
var totalNum = 0;
// 商品总金额
var totalAmount = 0;
// 获取商品数量控件<input:number>
var numbers = document.querySelectorAll("input[type=number]");
// 获取所有商品单价
var prices = document.querySelectorAll("tbody > tr > td:nth-of-type(5)");
// 1. 生成商品数量: 数组
counts = getCounts(numbers);
function getCounts(numbers) {
// Array.from(numbers): 将类数组,转为真正数组
// map()与forEach()功能相同, 只不过他返回一个新数组
return Array.from(numbers).map(function (item) {
return parseInt(item.value);
});
}
console.log(counts);
// 2. 商品单价: 数组
unitPrices = getUnitPrices(prices);
function getUnitPrices(prices) {
return Array.from(prices).map(function (item) {
// 拿到里面文本的值innerText
return parseInt(item.innerText);
});
}
console.log(unitPrices);
// 3. 计算每个商品的金额之和
amounts = getEveryAmount(counts, unitPrices);
function getEveryAmount(counts, unitPrices) {
var result = [];
for (var i = 0; i < unitPrices.length; i++) {
// 金额 = 单价 * 数量
amount = unitPrices[i] * counts[i];
// 将这个商品金额添加到金额数组中
result.push(amount);
}
return result;
}
console.log(amounts);
// 将每个商品金额渲染到页面中
var subtotal = document.querySelectorAll("tbody > tr > td:last-of-type");
// forEach(function (value,[ key, array]))
subtotal.forEach(function (sub, index) {
sub.innerHTML = amounts[index];
});
// 4. 计算数量总和
totalNum = numTotal(counts);
// reduce()归并,最终将所有数组元素累加成一个值返回
function numTotal(counts) {
return counts.reduce(function (prev, next) {
// 累加
return (prev += next);
}, 0);
}
console.log(totalNum);
// 将数量之和添加到页面中
document.getElementById("total-num").innerText = totalNum;
// 5 计算所有商品总金额
totalAmount = getTotalAmount(amounts);
function getTotalAmount(amounts) {
return amounts.reduce(function (prev, next) {
return (prev += next);
}, 0);
}
console.log(totalAmount);
// 将总金额添加到页面中
document.getElementById("total-price").innerText = totalAmount;
// 6. 给每个数量控件添加change事件
numbers.forEach(function (item) {
item.addEventListener("change", autoCalculate, false);
});
function autoCalculate(ev) {
// 更新总数量
counts = getCounts(numbers);
totalNum = numTotal(counts);
document.getElementById("total-num").innerText = totalNum;
// 更新每件商品的金额
var subtotal = document.querySelectorAll("tbody > tr > td:last-of-type");
subtotal.forEach(function (sub, index) {
sub.innerHTML = amounts[index];
});
// 每个商品的金额之和
amounts = getEveryAmount(counts, unitPrices);
// 更新总金额
totalAmount = getTotalAmount(amounts);
document.getElementById("total-price").innerText = totalAmount;
}
- 总结:
- 横向计算商品数量*单价,得到一种商品总金额
- 竖向计算所有商品总数量和总金额
- 添加数量增加的事件,更新总数量,总金额到页面中去