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

确实,input
事件在 contenteditable
元素上触发时,event.target
指向的是整个 contenteditable
容器,而不是被修改的具体子节点。因此,直接通过 event.target
是无法获取到被修改的子节点的。
为了检测具体哪个子节点被修改,可以通过以下方法实现:
方法:手动比较内容变化
在 input
事件触发时,手动比较当前内容和上一次记录的内容,找出被修改的子节点。
实现步骤
-
在页面加载时,保存所有子节点的初始内容。
-
在
input
事件触发时,重新获取所有子节点的当前内容。 -
比较当前内容和初始内容,找出被修改的子节点。
示例代码
<!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>
代码解释
-
保存初始内容:
-
在页面加载时,通过
Array.from(editableDiv2.children)
获取所有子节点,并保存每个子节点的id
和textContent
。 -
将这些信息存储在
previousContent
数组中。
-
-
监听
input
事件:-
当用户在
contenteditable
容器中输入内容时,input
事件会被触发。 -
在事件处理函数中,重新获取所有子节点的当前内容,并存储到
currentContent
数组中。
-
-
比较内容变化:
-
遍历
currentContent
,通过id
找到对应的初始内容。 -
如果当前内容与初始内容不同,则认为该子节点被修改。
-
输出被修改的子节点的
id
和新内容。
-
-
更新基准内容:
- 将当前内容更新为新的基准,以便下一次比较。
输出示例
假设用户修改了 id="child2"
的内容,控制台将输出:
被修改的子节点:
ID: child2, 新内容: 新的内容
注意事项
-
性能优化:如果子节点数量较多,频繁地比较内容可能会导致性能问题。可以通过节流(throttle)或防抖(debounce)技术来优化性能。
-
动态内容 :如果子节点是动态添加或删除的,需要在添加或删除时更新
previousContent
数组。 -
内容格式:如果子节点的内容包含HTML标签,需要根据实际需求调整比较逻辑。
通过这种方法,即使使用 input
事件,也可以检测到具体哪个子节点的内容被修改,并输出其 id
。