我需要捕获
contenteditable
元素中的所有输入并处理代码中的输入。基本上,我需要的是防止输入事件更改元素中的数据并知道要插入哪些数据。
我尝试了几乎所有可能的事件,但我总是遇到一些意想不到的行为。
例如。
第一个也是最明显的 -
keydown
事件。它适用于桌面浏览器,几乎不适用于移动设备,并且完全忽略输入法编辑器(IME、win/meta + .)。
接下来是
textInput
活动。同样的问题,但使用 IME 效果更好一些。
现在我发现
beforeInput
可能是更通用的解决方案。我尝试在寻找 inputType
(它可以告诉当前操作 - insertContent、removeWordForward 等)和 data
属性时使用它,但它在 Safari 中不能完全工作(并且我无法调试它)现在)。而且 IME 也不可靠。
奖金回合是自定义移动键盘,如 Microsoft Swift Keyboard,它的行为绝对不可预测,我不知道如何处理。例如,它可以具有单词自动完成功能 - 无论如何都没有关于此的信息。
也许有解决方法?我尝试使用文本编辑器检查开源存储库,这看起来确实是一项不平凡的任务,因为我发现它们使用我列出的每个事件,并且它们有很多逻辑来处理它们
引用OP的问题...
“基本上,我需要的是防止输入事件更改元素中的数据,并知道要插入哪些数据。”
这可以简单地通过查询具有
contenteditable
属性并且此外真正内容可编辑的所有元素来实现。
可以将每个元素节点的默认状态存储在例如通过节点引用的
WeakMap
实例,该引用引用具有例如元素的原始 innerHTML
和 textContent
值的对象。
如果发生基于“输入”事件的内容更改,将立即通过设置原始
innerHTML
值来恢复默认值。
// the node reference based storage of editable element's text-contents.
const editableContentStorage = new WeakMap;
function suppressEditableTextContentChange(evt) {
const { currentTarget } = evt;
debugger;
const {
defaultHtml,
defaultText,
} = editableContentStorage.get(currentTarget);
const changedContent = currentTarget.textContent;
// immediately restore default content.
currentTarget.innerHTML = defaultHtml;
console.log({ defaultText, changedContent });
}
document
// for every element which features
// a `contenteditable` attribute ...
.querySelectorAll('[contenteditable]')
// ... enable the handling of a custom
// 'input:datachange' event in case of
// an editable element.
.forEach(elmNode => {
if (elmNode.contentEditable === 'true') {
editableContentStorage
.set(elmNode, {
defaultHtml: elmNode.innerHTML,
defaultText: elmNode.textContent,
});
elmNode
.addEventListener('input', suppressEditableTextContentChange);
}
});
body { margin: 0; }
h2 { margin: 5px 0; font-size: 1.1em; }
p { margin: 5px 0; }
article { width: 20%; }
.as-console-wrapper { left: auto!important; width: 76%; min-height: 100%!important; }
<article contenteditable>
<h2>Some header copy</h2>
<p>Lorem ipsum dolor sit amet.</p>
<p>
The quick <b>brown fox</b> jumps over the
<b>
<em>lazy</em>
dog
</b>.
</p>
</article>