使document.execCommand('insertText',false,'message')与draftjs一起工作? [英] make document.execCommand('insertText', false, 'message') work with draftjs?

查看:421
本文介绍了使document.execCommand('insertText',false,'message')与draftjs一起工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个需要将文本插入 contenteditable = true div( Draftjs

I'm working on an application which needs to insert text into a contenteditable="true" div (a Draftjs based textfield to be precise).

现在,我知道Draft.js使用react并且应该以这种方式使用,但是在这种情况下,应用程序

Now I am aware that Draft.js uses react and that it should be used that way, but in this case, the application already exists and this is a third party electron app that works with it.

我正在macOS上进行在线通知回复,因此我需要将该回复文本发送给粘贴到draftJS字段中,但是,当我使用以下方法粘贴时:

I'm working on in-line notification replying on macOS, so I need that reply text to be pasted inside the draftJS field, however, when I do so using:

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

它会引发错误:

It throws an error:

我能够使用以下命令使其工作:

I was able to make it work using:

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

,但此API已被弃用,如果消息中包含表情符号,则该API无法正常工作。

but this API is deprecated and doesn't work properly if the message contains an emoji.

有没有办法做到这一点而不会导致错误?
我发现应该替换initTextEvent的新API只是 new Event()(请参阅 docs ),但我无法确定它是否支持textInput事件。

Is there any way to do this that doesn't cause an error? I found out that the new API that is supposed to replace initTextEvent is just new Event() (see docs), but I can't find out if it supports textInput events.

要使用它,您可以转到 https:// draftjs.org/ 并在chrome开发工具中使用它。

To play around with it you can just go to https://draftjs.org/ and play with it in chrome dev tools.

我真的很感谢这里的帮助,因为我不知道该怎么做。它工作了。另外,我知道人们是jquery的爱好者,但我更喜欢本机js解决方案(尽管可以使用任何解决方案)。

I would really appreciate some help here as I don't know what to do to make it work anymore. Also, I know people are a fan of jquery, but I'd prefer a native js solution (although any solution is welcome).

编辑:

请注意:
我没有使用react,我要修改的输入字段(draftjs)正在使用react,我想输入文本

Please note: I'm not using react, the input field I want to modify (draftjs) is using react and I want to input text into it using native js.

编辑2:

对于其他人在此问题上,我想将文本插入Facebook Messenger文本字段(使用DraftJS)。

For anyone else coming across this issue, I wanted to insert text into the Facebook messenger text field (which uses Draftjs).

我设法找到了一种可行的解决方法。
它确实使用了已弃用的API( event.initTextEvent ),但这是我发现的唯一可行的方法,即使使用表情符号也是如此。 如果您有更好的解决方案,请发布答案。
它的工作原理如下:

I managed to find a working workaround. It does use the deprecated API (event.initTextEvent), but it's the only way that I've found that works, even with emoji. Please do post an answer if you have a better solution to this. It works like this:

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内插入一个占位符值来工作,然后将该文本替换为:

It works by inserting a placeholder value inside the textField using event.initTextEvent, and then replacing that text with:

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

在Chrome中测试:版本71.0.3578.98

推荐答案

尽管很久以前就问过这个问题,并且@JoniVR找到了解决方法,但这可能会对其他人有所帮助。

Although the question was asked a long ago and @JoniVR found a workaround, this may help someone else.

在进行扩展时,我也遇到了类似的问题。我还尝试了document.execCommand('insertText',false,text)方法。它在LinkedIn上有效,但在Facebook上无效。它在错误的节点中插入了文本。尽管 document.execCommand API在某些地方有效,

I was also having a similar problem while working on an extension. I also tried the method document.execCommand('insertText', false, text). It worked on LinkedIn but not on Facebook. It was inserting text in the wrong node. Although document.execCommand API works in some places, it's obsolete now.

对于Facebook和其他使用drafjs编辑器的网站,我们需要使用数据传输 clipBoardEvent API,以使draftjs认为粘贴了文本并进行了相应处理。

For Facebook and any other sites using drafjs editor, We need to dispatch a paste event using dataTransfer and clipBoardEvent APIs to make draftjs think that the text is pasted and process accordingly.

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();
}

选中此链接,以防需要更多信息。

Check this link in case more info needed.

这篇关于使document.execCommand('insertText',false,'message')与draftjs一起工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆