思路
比较简单,基本上就步骤来,监听事件的时候可以监听父级节点利用点击事件冒泡一个监听就行了。
坑点
主要是 query 和 getElemnt 方法的区别:
- query 这类方法选择符选出来的元素及元素数组是静态的,不会随着文档操作而改变。query 使用比较方便。常用的
querySelector-单选,querySelectorAll-多选 - getElement 这类方法选出的元素是动态的,能查到修改后的
dom。getElement 这类方法性能比较好。常用的getElementById-单选,getElementsByClassName、getElementsByClassName、getElementsByTagName、getElementsByName等-多选。
代码
function show(total, count) {
document.getElementsByTagName(
"tfoot"
)[0].children[0].children[1].innerHTML = `${total.toFixed(
2
)}(${count}件商品)`;
// !!! querySelector 不能实时获取 dom 变化
// const tdDom = document.querySelector("tfoot td");
// tdDom.innerHtml = `${total.toFixed(2)}(${count}件商品)`;
}
function calc() {
const trs = document
.getElementsByTagName("tbody")[0]
.getElementsByTagName("tr");
let total = 0,
count = 0;
// !!! querySelectorAll 静态的 不能实时获取 dom 变化
// const tds = document.querySelectorAll("tbody td:nth-child(2)");
// tds.forEach(
// (item) => ((total += parseFloat(item.textContent)), (count += 1))
// );
Array.prototype.forEach.call(
trs,
(tr) => (total += parseFloat(tr.children[1].textContent))
);
// !!! 不支持 for of
// for (let tr of trs) {
// total += parseFloat(tr.children[1].textContent);
// }
show(total, trs.length);
}
function add(items) {
const tbodyDom = document.getElementsByTagName("tbody")[0];
let html = tbodyDom.innerHTML;
items.forEach((i) => {
html += `<tr><td>${i.name}</td><td>${i.price.toFixed(
2
)}</td><td><a href="javascript:void(0);">删除</a></td></tr>`;
});
tbodyDom.innerHTML = html;
calc();
}
function bind() {
const tbodyDom = document.getElementsByTagName("tbody")[0];
tbodyDom.addEventListener("click", (evt) => {
const target = evt.target;
if (target.nodeName === "A") {
target.parentElement.parentElement.remove();
calc();
}
});
} 
京公网安备 11010502036488号