JS检测htm哪个子节点的内容被修改addEventListener(‘input‘, (event)

监听 input 事件,editableDiv2.addEventListener('input', (event) => {无法检测哪个子节点ID被改变

编辑

复制

确实,input 事件在 contenteditable 元素上触发时,event.target 指向的是整个 contenteditable 容器,而不是被修改的具体子节点。因此,直接通过 event.target 是无法获取到被修改的子节点的。

为了检测具体哪个子节点被修改,可以通过以下方法实现:

方法:手动比较内容变化

input 事件触发时,手动比较当前内容和上一次记录的内容,找出被修改的子节点。

实现步骤
  1. 在页面加载时,保存所有子节点的初始内容。

  2. input 事件触发时,重新获取所有子节点的当前内容。

  3. 比较当前内容和初始内容,找出被修改的子节点。

示例代码
复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Editable Content Detection</title>
</head>
<body>
    <div id="editableDiv2" contenteditable="true">
        <div id="child1">Child 1</div>
        <div id="child2">Child 2</div>
        <div id="child3">Child 3</div>
    </div>

    <script>
        // 获取可编辑的父元素
        const editableDiv2 = document.getElementById('editableDiv2');

        // 保存初始内容
        let previousContent = Array.from(editableDiv2.children).map(child => ({
            id: child.id,
            text: child.textContent
        }));

        // 监听 input 事件
        editableDiv2.addEventListener('input', () => {
            // 获取当前内容
            const currentContent = Array.from(editableDiv2.children).map(child => ({
                id: child.id,
                text: child.textContent
            }));

            // 比较当前内容和上一次记录的内容
            const changes = currentContent.filter(item => {
                const previousItem = previousContent.find(p => p.id === item.id);
                return previousItem && previousItem.text !== item.text;
            });

            // 输出被修改的子节点
            if (changes.length > 0) {
                console.log('被修改的子节点:');
                changes.forEach(change => {
                    console.log(`ID: ${change.id}, 新内容: ${change.text}`);
                });
            }

            // 更新当前内容为新的基准
            previousContent = currentContent;
        });
    </script>
</body>
</html>

代码解释

  1. 保存初始内容

    • 在页面加载时,通过 Array.from(editableDiv2.children) 获取所有子节点,并保存每个子节点的 idtextContent

    • 将这些信息存储在 previousContent 数组中。

  2. 监听 input 事件

    • 当用户在 contenteditable 容器中输入内容时,input 事件会被触发。

    • 在事件处理函数中,重新获取所有子节点的当前内容,并存储到 currentContent 数组中。

  3. 比较内容变化

    • 遍历 currentContent,通过 id 找到对应的初始内容。

    • 如果当前内容与初始内容不同,则认为该子节点被修改。

    • 输出被修改的子节点的 id 和新内容。

  4. 更新基准内容

    • 将当前内容更新为新的基准,以便下一次比较。

输出示例

假设用户修改了 id="child2" 的内容,控制台将输出:

复制代码
被修改的子节点:
ID: child2, 新内容: 新的内容

注意事项

  • 性能优化:如果子节点数量较多,频繁地比较内容可能会导致性能问题。可以通过节流(throttle)或防抖(debounce)技术来优化性能。

  • 动态内容 :如果子节点是动态添加或删除的,需要在添加或删除时更新 previousContent 数组。

  • 内容格式:如果子节点的内容包含HTML标签,需要根据实际需求调整比较逻辑。

通过这种方法,即使使用 input 事件,也可以检测到具体哪个子节点的内容被修改,并输出其 id

相关推荐
岩柏1 分钟前
在vue项目中添加stylelint
前端
暖苏3 分钟前
Vue.js第一节
前端·javascript·css·vue.js·ecmascript
前端服务区7 分钟前
NodeJS文件流
前端
菜鸡且互啄699 分钟前
前端打断点
前端
jason_yang17 分钟前
watchEffect的flush属性你都用过不?
前端·vue.js
云深不知处_18 分钟前
RE0_OC_1
前端·ios
uio21 分钟前
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
前端·vue.js
小浪努力学前端44 分钟前
React + ECharts:给tooltip里的按钮绑定事件,我踩过的那些坑
前端·react.js·echarts
不像程序员的程序媛1 小时前
es按时间 小时聚合
java·前端·elasticsearch
bobz9651 小时前
为什么 不能在浏览器里直接用 Node.js 专用模块?
前端