querySelectorAll() 不会实时更新获取到的元素节点结合 - 简单留言案例删除留言

项目场景:

使用 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>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`querySelectorAll()` 是用于在文档中选择匹配指定CSS选择器的所有元素的方法。如果返回的结果为空,可能有以下几个原因: 1. **选择器不准确**[^4]: 如果你使用的CSS选择器无法精确地匹配到任何元素,`querySelectorAll()` 将不会找到任何结果。例如,如果你试图通过 `.myClassThatDoesNotExist` 获取元素,因为这个类不存在,它会返回空。 2. **DOM树更新**[^5]: 当页面结构发生变化(比如动态添加或移除元素),并且这些变化发生在`querySelectorAll()`调用之后,可能会导致匹配不到元素。在这种情况下,你应该确保选择器在元素添加到文档之前已经生效。 3. **JavaScript延迟执行**[^6]: 如果查询是在某个事件(如`DOMContentLoaded`)触发后执行的,但在此期间元素尚未加载完成,也可能导致找不到元素。这时可以考虑将查询放在回调函数里以确保元素已存在。 4. **浏览器兼容性**[^7]: 虽然`querySelectorAll()`在现代浏览器中很常见,但在一些较旧的浏览器中可能不支持。确保你的代码能在目标浏览器上正常工作。 要解决这个问题,你可以尝试调试代码,确认选择器是否正确,以及是否在正确的时间执行了查询。如果是因为兼容性问题,可以考虑使用polyfill来增强老版本浏览器的支持。 ```javascript // 示例代码 let elements = document.querySelectorAll('.yourSelector'); if (elements.length === 0) { console.error('No elements found with the given selector.'); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值