场景:通过javascript为ul标签内动态增删li标签,我通过 liArr = ul.children;
获取了ul的存有所有子元素的类数组,但是在 appendChild()
、insert()
和removeChild()
的过程中,发现这个 liArr
数组在动态变化,但是每次增删子元素的时候代码中并没有更新 liArr
的数据。
自己的理解:在增删修改子元素的时候,其对应的类数组 (ul.children)
会随之动态变化,不用自己来更新数组的数据,好像仔细想想确实是这么回事,因为 liArr
引用始终指向的是 ul.children
所占用的堆内存空间,在增删改ul的子元素的时候,这个堆内存空间的存放数据会随之动态变化,那么导致 liArr
类数组也会随之变化。
代码:
<script>
var ul;
var liArr;
var input;
var btn1, btn2, btn3;
var check;
initNode();
// 清空城市
myClick(btn3, function () {
var n = liArr.length;
// 遍历li,把除了内容为北京、上海、重庆的标签全删除
for (var i = 0; i < n; i++) {
if (liArr[0].innerText != "重庆" && liArr[0].innerText != "北京" && liArr[0].innerText != "上海") {
ul.removeChild(liArr[0]);
}
}
// 不能用下面代码来清空标签,因为liArr数组在ul对象移除子节点的时候会动态变化(????????不知道为什么会变化)
/*
for (var i = 0; i < liArr.length; i++) {
if (liArr[i].innerText != "重庆" && liArr[i].innerText != "北京" && liArr[i].innerText != "上海") {
ul.removeChild(liArr[i]);
}
}
*/
});
// 添加城市
myClick(btn1, function () {
// 获取input输入的框的值用其创建一个文本节点
var textNode = document.createTextNode(input.value);
// 创建一个li元素节点对象
var li = document.createElement("li");
// 设置li元素节点对象的子节点为文本节点
li.appendChild(textNode);
// 获取checkbox状态
var isAppend = check.checked;
if (isAppend) {
// 判断添加的城市是否存在
if (isExisted(li)) {
input.value = "";
alert("请忽重复添加城市");
} else {
input.value = "";
// 将li元素节点对象往后添加到ul元素节点中
ul.appendChild(li);
}
} else {
if (isExisted(li)) {
input.value = "";
alert("请忽重复添加城市");
} else {
// 在ul的第一个li前面插入新的li
input.value = "";
ul.insertBefore(li, ul.firstElementChild);
}
}
});
function isExisted(element) {
// 获取所有的li
var liArr = document.getElementsByTagName("li");
for (var i = 0; i < liArr.length; i++) {
if (liArr[i].innerText == element.innerText) return true;
}
return false;
}
function initNode() {
ul = document.querySelector("ul");
liArr = ul.children;
input = document.getElementById("input-city");
btn1 = document.querySelector(".add");
btn2 = document.querySelector(".delete");
btn3 = document.querySelector(".clear");
check = document.getElementById("isAppend");
}
function myClick(btn, fun) {
btn.onclick = fun;
}
</script>