gpt4 book ai didi

javascript - 获取更改前 contenteditable 元素的 textContent(或 `beforeinput` )

转载 作者:行者123 更新时间:2023-11-29 15:15:47 25 4
gpt4 key购买 nike

我有 <ol contenteditable=true>元素,我想添加一个 eventListener,以便任何 <li> 中的任何更改之前在这些列表中,原始 textContent (即,任何更改之前的文本)被推送到 var alterations = [] .

我试过使用 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>

但是beforeinput似乎不适用于 contenteditable 元素(如上面的代码所示,未执行回调函数)。只有 input事件作为 addEventListener 的参数, 但为时已晚,因为已经输入或从原始文本中删除了一个字母。

问题:如何通过contenteditable获取即将改变的元素的原文?例如,如果我输入“第一”<li>其他东西,比如“not First”,我怎么能推送原来的 textContent <li> 的(=== 只是“第一个”)到 alterations数组?


编辑:我认为这是浏览器问题。 beforeinput适用于基于 Chromium 的浏览器,但不适用于基于 Firefox 的浏览器(如 Firefox 和 PaleMoon)。我的快速修复是使用 keydown而不是 beforeinput .此代码适用于所有浏览器:

 for (let x of document.querySelectorAll('[contenteditable="true"]')) {
x.addEventListener('keydown',() => {
let originalText = window.getSelection().anchorNode.textContent;
console.log(originalText);
});

但这有一个不幸的问题,即每次按下任何键时都会触发,例如Ctrl+ShiftAlt。我试过 keypress而不是 keydown ,但是我的基于 Chromium 的浏览器没有触发删除,任何按下的“上/下/左/右/”键也会触发代码。我想我可以用 charcode 一一处理这些异常, 但除了使用 keydown 没有别的办法吗? ?

最佳答案

好的,这里应该可以工作:

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>

这在兼容性方面似乎是最好的,因为我开始认为每个浏览器对 beforeinput 都有不同的响应。 (也许在没有处理程序的情况下到 keydown)。我下载了一个基于 Chromium 的浏览器来测试它,结果似乎与 Chrome 不同。

编辑:我替换了 event.which对于 event.key ,因为前者已被弃用并且在不同的浏览器中工作不可靠。

遗留问题:

  1. 如果用户重复输入 ~~~´´´´等,这不会处理。
  2. 如果用户复制文本 (Ctrl+C),或在 <li> 时使用另一个类似的快捷方式是焦点,然后事件将不情愿地被触发,因为它听了 c . [感谢@trysis 评论修复]

关于javascript - 获取更改前 contenteditable 元素的 textContent(或 `beforeinput` ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49275267/

25 4 0