html 获取contenteditable中发生keydown的元素

ki0zmccv  于 2023-03-11  发布在  其他
关注(0)|答案(3)|浏览(174)

我有一个div,它是contenteditable,这个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.捕获并阻止事件以更新内部数据结构
1.从数据结构呈现React组件
并且这似乎不是对此的适当解决方案。

mm5n2pyu

mm5n2pyu1#

你可以把keydown事件附加到你的文档的主体上,然后在keydown事件发生时,使用document.activeElement返回当前有焦点的元素,并接收键盘输入。
这里有一个解释文档的链接。activeElement(https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement

plicqrtu

plicqrtu2#

你可以把监听器放在contenteditable元素上,然后通过比较新文本和旧文本来检查哪个元素被更新了,并根据这一点,你可以在相应的分支中执行你的操作。
检查这个代码块-

<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>
cmssoen2

cmssoen23#

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

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

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

相关问题