簡體   English   中英

使 document.execCommand('insertText', false, 'message') 與 Draftjs 一起工作?

[英]make document.execCommand('insertText', false, 'message') work with draftjs?

我正在開發一個需要將文本插入contenteditable="true" div( Draftjs基於Draftjs的文本字段)的應用程序。

現在我知道 Draft.js 使用 react 並且應該以這種方式使用它,但在這種情況下,該應用程序已經存在並且這是一個與它配合使用的第三方電子應用程序。

我正在 macOS 上處理在線通知回復,因此我需要將該回復文本粘貼到 DraftJS 字段中,但是,當我這樣做時,使用:

document.querySelector('div[contenteditable="true"]').focus();
document.execCommand('insertText', false, 'message');

它拋出一個錯誤: 錯誤圖像

我能夠使用以下方法使其工作:

const event = document.createEvent('TextEvent');
event.initTextEvent('textInput', true, true, window, 'message', 0, locale);

但如果消息包含表情符號,則此 API 已棄用且無法正常工作。

有沒有辦法做到這一點,不會導致錯誤? 我發現應該替換 initTextEvent 的新 API 只是new Event() (請參閱文檔),但我不知道它是否支持 textInput 事件。

要使用它,您可以訪問https://draftjs.org/並在 chrome 開發工具中使用它。

我真的很感激這里的一些幫助,因為我不知道該怎么做才能讓它繼續工作。 另外,我知道人們是 jquery 的粉絲,但我更喜歡原生 js 解決方案(盡管歡迎任何解決方案)。

編輯:

請注意:我沒有使用 react,我要修改的輸入字段 (draftjs) 使用的是 react,我想使用原生 js 向其中輸入文本。

編輯2:

對於遇到此問題的其他人,我想將文本插入 Facebook 信使文本字段(使用 Draftjs)。

我設法找到了一個可行的解決方法。 它確實使用了已棄用的 API ( event.initTextEvent ),但這是我發現的唯一有效方法,即使使用表情符號也是如此。 如果您對此有更好的解決方案,請發布答案。 它是這樣工作的:

async function sendReply(message: string): Promise<void> {
       const inputField = document.querySelector('[contenteditable="true"]') as HTMLElement;
       if (inputField) {
               const previousMessage = inputField.textContent;
               // Send message
               inputField.focus();
               await insertMessageText(message, inputField);
               (await elementReady('._30yy._38lh._39bl')).click();
               // Restore (possible) previous message
               if (previousMessage) {
                       insertMessageText(previousMessage, inputField);
               }
       }
}

function insertMessageText(text: string, inputField: HTMLElement): void {
       // Workaround: insert placeholder value to get execCommand working
       if (!inputField.textContent) {
               const event = document.createEvent('TextEvent');
               event.initTextEvent('textInput', true, true, window, '_', 0, '');
               inputField.dispatchEvent(event);
       }

       document.execCommand('selectAll', false, undefined);
       document.execCommand('insertText', false, text);
}

這是打字稿代碼,因此您可能需要將其更改為使用 js。

它的工作原理是使用event.initTextEvent在 textField 中插入一個占位符值,然后將該文本替換為:

document.execCommand('selectAll', false, undefined);
document.execCommand('insertText', false, 'text');

在 Chrome 中測試:版本 71.0.3578.98

盡管很久以前就有人問過這個問題並且@JoniVR 找到了解決方法,但這可能對其他人有所幫助。

我在開發擴展時也遇到了類似的問題。 我還嘗試了方法 document.execCommand('insertText', false, text)。 它適用於 LinkedIn,但不適用於 Facebook。 它在錯誤的節點中插入文本。 盡管document.execCommand API 在某些地方有效,但它現在已經過時了。

對於 Facebook 和任何其他使用 drafjs 編輯器的站點,我們需要使用dataTransferclipBoardEvent API 調度一個 paste 事件,使 Draftjs 認為文本已粘貼並進行相應的處理。

const dataTransfer = new DataTransfer();

function dispatchPaste(target, text) {
  // this may be 'text/html' if it's required
  dataTransfer.setData('text/plain', text);

  target.dispatchEvent(
    new ClipboardEvent('paste', {
      clipboardData: dataTransfer,

      // need these for the event to reach Draft paste handler
      bubbles: true,
      cancelable: true
    })
  );

  // clear DataTransfer Data
  dataTransfer.clearData();
}

如果需要更多信息,請檢查此鏈接

暫無
暫無

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

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