获取在内容可编辑中发生的键控元素



我有一个contenteditablediv,并且div有一些内容:

<div contenteditable="true" id="editable-div">
<p id="paragraph">
Lorem <em>ipsum</em> dolor sit <strong id="stong-el">amet</strong>
<p>
</div>

我想拦截keydown事件并找到用户尝试写入的元素。

在侦听内容可编辑的div时,我已经找不到特定的元素:

const div = document.getElementById('editable-div');
div.addEventListener('keydown', event => { /* ??? */ }, false);

问题:回调中的事件没有告诉我哪个元素被写入了,它只告诉我我已经写了#editable-div

我的另一个尝试是侦听嵌套事件,如下所示:

// either
const el = document.getElementById('paragraph');
// or
const el = document.getElementById('stong-el');
el.addEventListener('keydown', event => { /* ??? */ }, false);

这样做的问题是事件永远不会触发。显然,该事件仅在具有contenteditable属性的元素上触发,这有点糟糕。

我最后的手段是监听#editable-div并检查哪个元素具有文本选择,但如果有任何其他方法,我宁愿不这样做。

更新

我发现的另一种方法是在可编辑元素上使用MutationObserver,如下所示:

const observer = new MutationObserver(mutations => {
mutations.forEach(function(mutation) {
console.log(mutation.target);
});
});
const config = { characterData: true, subtree: true };
const div = document.getElementById('editable-div');
observer.observe(div, config);

这将记录我编辑的文本元素。

我不确定我的问题是否得到了回答,因为最终我想做两件事:

  1. 捕获并阻止事件以更新内部数据结构
  2. 从数据结构渲染 React 组件

这似乎不是一个合适的解决方案。

您可以检查当前文本选择的focusNode,以获取发生键合事件的 DOM 节点:

const div = document.getElementById('editable-div');
div.addEventListener('keydown', event => {
console.log(window.getSelection()?.focusNode);
}, false);

https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection

您可以将 keydown 事件附加到文档的正文。然后在键向下事件时,使用 document.activeElement 返回当前具有焦点并将接收键盘输入的元素。

这是一个解释document.activeElement(https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement)的链接

您可以将侦听器放在内容可编辑元素上,然后通过比较其新文本和旧文本来检查哪个元素已更新。根据这一点,您可以在各自的分支中执行操作。

检查此代码块 -

<div id="ce" contenteditable="true">
<strong id="s">Abc</strong><br/>
<i id="i">Hello</i>
</div>
<script>
oldstext = document.getElementById('s').textContent;
olditext = document.getElementById('i').textContent;
document.getElementById('ce').addEventListener('keydown', event => { 
//alert("ce Edited");
if(oldstext != document.getElementById('s').textContent){
console.log(oldstext + "   v/s  " + document.getElementById('s').textContent);
oldstext = document.getElementById('s').textContent;
}
else if (olditext != document.getElementById('i').textContent){
console.log(olditext + "   v/s  " + document.getElementById('i').textContent);
olditext = document.getElementById('i').textContent;
}

}, false);
</script>

最新更新