electron 将文本插入现有/外部draftjs文本字段

jgovgodb  于 2022-12-16  发布在  Electron
关注(0)|答案(1)|浏览(176)

我正在开发一个应用程序,它需要将文本插入到contenteditable="true" div(准确地说,是基于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已过时,如果消息包含表情符号,则无法正常工作。
有没有什么方法可以做到这一点,而不会导致错误?我发现,新的API是应该取代initTextEvent只是new Event()(请参阅docs),但我不能确定它是否支持textInput事件。
要玩它,你可以直接进入https://draftjs.org/,在chrome开发工具中玩它。
我真的很感激这里的一些帮助,因为我不知道该怎么做才能让它工作下去,而且,我知道人们都是jquery的粉丝,但我更喜欢一个原生的js解决方案(尽管任何解决方案都是受欢迎的)。

编辑:

请注意:我没有使用react,我想修改的输入域(draftjs)使用react,我想用原生js输入文本。

编辑2:

对于遇到这个问题的其他人,我想在Facebook Messenger文本字段(使用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*
r7xajy2e

r7xajy2e1#

虽然这个问题很久以前就被问到了,@JoniVR找到了一个变通办法,但这可能会帮助其他人。
我在开发扩展时也遇到了类似的问题。我也尝试了document.execCommand('insertText',false,text)方法。它在LinkedIn上有效,但在Facebook上无效。它在错误的节点中插入文本。虽然document.execCommand API在某些地方有效,但现在已经过时了。
对于Facebook和任何其他使用drafjs编辑器的网站,我们需要使用dataTransferclipBoardEvent API发送一个粘贴事件,使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();
}

如果需要更多信息,请查看此链接。

相关问题