项目场景:
使用 document.querySelectorAll() 选择的元素列表不会实时更新,即元素改变之后,元素集合不会改变。
问题描述:
简单留言案例 - 错误代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>留言案例</title>
<style>
textarea {
resize: none;
font-size: 20px;
padding: 10px;
outline: none;
}
ul li {
background-color: lightblue;
width: 300px;
}
ul li a {
display: block;
}
</style>
</head>
<body>
<div class="box">
<textarea name="" id="" cols="50" rows="10" class="texting_box" placeholder="请输入内容..."></textarea>
<button>发布</button>
<ul></ul>
</div>
<script>
// 获取按钮
let btn = document.querySelector('button');
let texting = document.querySelector('textarea');
let uls = document.querySelector('ul');
let dels = document.querySelectorAll('a');
// 点击按钮之后获取文本框的留言进行发布
btn.onclick = function () {
// 创建新的 li 节点
let newli = document.createElement('li');
// 获取用户输入的内容
newli.innerHTML = texting.value + '<a href="javascript:;">删除</a>';
uls.appendChild(newli);
// 清空输入
texting.value = '';
}
// 这里原本是想为每个 <a> 添加点击事件,当点击删除之后就删除该留言
// 但是由于 querySelectorAll() 是 non-live 的,获取到的元素集合不会随元素的改变实时更新,
// 所以获取到的永远是一个空节点集合
for (let i = 0; i < dels.length; i++) {
dels[i].onclick = function () {
uls.removeChild(this.parentNode);
}
}
</script>
</body>
</html>
原因分析:
querySelectorAll() 是 non-live 的,获取到的元素集合不会随元素的改变实时更新
解决方案:
修改获取 <a> 的和绑定点击删除事件的位置,每次点击“发布”按钮都重新获取 <a> 节点集合并注册点击事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>留言案例</title>
<style>
textarea {
resize: none;
font-size: 20px;
padding: 10px;
outline: none;
}
ul li {
background-color: lightblue;
width: 300px;
}
ul li a {
display: block;
text-align: right;
}
</style>
</head>
<body>
<div class="box">
<textarea name="" id="" cols="50" rows="10" class="texting_box" placeholder="请输入内容..."></textarea>
<button>发布</button>
<ul></ul>
</div>
<script>
// 获取按钮
let btn = document.querySelector('button');
let texting = document.querySelector('textarea');
let uls = document.querySelector('ul');
// 点击按钮之后获取文本框的留言进行发布
btn.onclick = function () {
// 创建新的 li 节点
let newli = document.createElement('li');
// 获取用户输入的内容
newli.innerHTML = texting.value + '<a href="javascript:;">删除</a>';
uls.appendChild(newli);
// 清空输入
texting.value = '';
// 获取所有的 <a>,并注册点击事件
let dels = document.querySelectorAll('a');
for (let i = 0; i < dels.length; i++) {
dels[i].onclick = function () {
uls.removeChild(this.parentNode);
}
}
}
</script>
</body>
</html>