簡體   English   中英

在更改之前獲取contenteditable元素的textContent(或`beforeinput`)

[英]Get textContent of contenteditable element before change (or `beforeinput`)

我有<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獲取要更改的元素的原始文本? 例如,如果我輸入“First” <li>其他內容,例如“not First”,如何將<li>的原始textContent (===只是“First”)推送到alterations數組?


編輯:我認為這是一個瀏覽器問題。 beforeinput適用於基於Chromium的瀏覽器,但不適用於基於Firefox的瀏覽器(如Firefox和PaleMoon)。 我的quickfix是使用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.key替換了event.which ,因為前者已被棄用,並且在不同的瀏覽器中不可靠。

剩下的問題:

  1. 如果用戶重復類型~~~´´´´等等,這將不會被處理。
  2. 如果用戶復制文本( Ctrl + C ),或者在<li>聚焦時使用另一個類似的快捷方式,則會不情願地觸發事件,因為它會聽取c [感謝@trysis評論]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM