[英]Get textContent of contenteditable element before change (or `beforeinput`)
I have <ol contenteditable=true>
elements and I want to add an eventListener so that before any changes in any <li>
of these lists, the original textContent
(that is, the text prior to any alterations) is pushed to var alterations = []
. 我有
<ol contenteditable=true>
元素,我想添加一个eventListener,以便在任何<li>
这些列表中的任何更改之前 ,原始textContent
(即任何更改之前的文本)被推送到var alterations = []
。
I have tried using addEventListener("beforeinput", ...
, as follows: 我尝试过使用
addEventListener("beforeinput", ...
,如下所示:
window.alterations = []; window.onload = () => { document.getElementById('main').addEventListener("beforeinput", () => { alert('event listened!'); window.alterations.push(window.getSelection().anchorNode.parentElement.textContent); console.log(window.alterations); }); }
<body> <section id="main"> <ol contenteditable="true"> <li>First</li> <li>Second</li> <li>Third</li> <li>Fourth</li> </ol> <ol contenteditable="true"> <li>First</li> <li>Second</li> <li>Third</li> <li>Fourth</li> </ol> </section> </body>
But beforeinput
does not seem to work on contenteditable elements (as the above code shows, the callback function is not executed). 但是
beforeinput
似乎不适用于contenteditable元素(如上面的代码所示,回调函数没有执行)。 Only the input
event works as argument to addEventListener
, but then is too late, since one letter was already inputted or deleted from the original text. 只有
input
事件作为addEventListener
参数,但是为时已晚,因为已经从原始文本输入或删除了一个字母。
Question : how can I get the original text of the element about to be changed via contenteditable
? 问题 :如何通过
contenteditable
获取要更改的元素的原始文本? For example, if I type in the "First" <li>
something else, like "not First", how can I push the original textContent
(=== just "First") of the <li>
to the alterations
array? 例如,如果我输入“First”
<li>
其他内容,例如“not First”,如何将<li>
的原始textContent
(===只是“First”)推送到alterations
数组?
EDIT: I think this is a browser issue. 编辑:我认为这是一个浏览器问题。
beforeinput
works in Chromium based browsers, but not in Firefox based browsers (like Firefox and PaleMoon). beforeinput
适用于基于Chromium的浏览器,但不适用于基于Firefox的浏览器(如Firefox和PaleMoon)。 My quickfix was to use keydown
instead of beforeinput
. 我的quickfix是使用
keydown
而不是beforeinput
。 This code works in all browsers: 此代码适用于所有浏览器:
for (let x of document.querySelectorAll('[contenteditable="true"]')) {
x.addEventListener('keydown',() => {
let originalText = window.getSelection().anchorNode.textContent;
console.log(originalText);
});
But this has the unfortunate problem of triggering every time any key is pressed, like Ctrl + Shift or Alt . 但是每次按下任何键时都会触发这个不幸的问题,比如Ctrl + Shift或Alt 。 I tried
keypress
instead of keydown
, but my Chromium based browser didn't trigger on deletions and any "move up/down/left/right/" keys pressed will also trigger the code. 我尝试过
keypress
而不是keydown
,但我的基于Chromium的浏览器没有触发删除,按下任何“上移/下移/左/右/”按键也会触发代码。 I guess I can handle these exceptions one by one with charcode
, but is there no other way than using keydown
? 我想我可以用
charcode
处理这些异常,但除了使用keydown
之外别无他法吗?
OK, this here should work: 好的,这应该工作:
window.alterations = []; window.onload = () => { document.getElementById('main').addEventListener("keydown", (event) => { //0 == delete in PaleMoon, 46 == delete in other browsers /* ALT is needed for some characters, like § and º, but to exclude ALT, META, etc.: if (event.altKey || event.metaKey) {return;} */ if (event.key.length === 1 || ["Enter", "Delete", "Backspace"].includes(event.key)) { //when Ctrl is pressed, trigger only if Ctrl+V or Ctrl+X and ALT is not pressed: if (event.key.toLowerCase() !== 'v' && event.key.toLowerCase() !== 'x' && event.ctrlKey && !event.altKey) {return;} alert('event listened!'); window.alterations.push(window.getSelection().anchorNode.parentElement.textContent); console.log(window.alterations); } }); }
<body> <section id="main"> <ol contenteditable="true"> <li>First</li> <li>Second</li> <li>Third</li> <li>Fourth</li> </ol> <ol contenteditable="true"> <li>First</li> <li>Second</li> <li>Third</li> <li>Fourth</li> </ol> </section> </body>
And this seems to be best in terms of compatibility, since I'm starting to think each browser has a different response to beforeinput
(and maybe to keydown
without a handler). 这似乎在兼容性方面是最好的,因为我开始认为每个浏览器对
beforeinput
有不同的响应(并且可能没有处理程序的keydown
)。 I downloaded a Chromium based browser to test it and the results seem different than from Chrome. 我下载了一个基于Chromium的浏览器来测试它,结果与Chrome不同。
EDIT : I replaced event.which
for event.key
, since the former is deprecated and works unreliably in different browsers. 编辑 :我为
event.key
替换了event.which
,因为前者已被弃用,并且在不同的浏览器中不可靠。
Remaining problems: 剩下的问题:
~~~
or ´´´´
, etc., this will not be handled. ~~~
或´´´´
等等,这将不会被处理。 <li>
is focused, then event will unwillingly be triggered, since it listened to c
. <li>
聚焦时使用另一个类似的快捷方式,则会不情愿地触发事件,因为它会听取c
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.