使 document.execCommand('insertText', false, 'mes

2023-01-29前端开发问题
6

本文介绍了使 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');

它抛出一个错误:

我能够使用:

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

但如果消息包含表情符号,此 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,我想使用本机js向其中输入文本.

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 编辑器的网站,我们需要使用 dataTransfer 和 clipBoardEvent APIs让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 一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

js删除数组中指定元素的5种方法
在JavaScript中,我们有多种方法可以删除数组中的指定元素。以下给出了5种常见的方法并提供了相应的代码示例: 1.使用splice()方法: let array = [0, 1, 2, 3, 4, 5];let index = array.indexOf(2);if (index -1) { array.splice(index, 1);}// array = [0,...
2024-11-22 前端开发问题
182

JavaScript小数运算出现多位的解决办法
在开发JS过程中,会经常遇到两个小数相运算的情况,但是运算结果却与预期不同,调试一下发现计算结果竟然有那么长一串尾巴。如下图所示: 产生原因: JavaScript对小数运算会先转成二进制,运算完毕再转回十进制,过程中会有丢失,不过不是所有的小数间运算会...
2024-10-18 前端开发问题
301

JavaScript(js)文件字符串中丢失"\"斜线的解决方法
问题描述: 在javascript中引用js代码,然后导致反斜杠丢失,发现字符串中的所有\信息丢失。比如在js中引用input type=text onkeyup=value=value.replace(/[^\d]/g,) ,结果导致正则表达式中的\丢失。 问题原因: 该字符串含有\,javascript对字符串进行了转...
2024-10-17 前端开发问题
437

layui中table列表 增加属性 edit="date",不生效怎么办?
如果你想在 layui 的 table 列表中增加 edit=date 属性但不生效,可能是以下问题导致的: 1. 缺少日期组件的初始化 如果想在表格中使用日期组件,需要在页面中引入 layui 的日期组件,并初始化: script type="text/javascript" src="/layui/layui.js"/scrip...
2024-06-11 前端开发问题
455

Rails/Javascript:如何将 rails 变量注入(非常)简单的 javascript
Rails/Javascript: How to inject rails variables into (very) simple javascript(Rails/Javascript:如何将 rails 变量注入(非常)简单的 javascript)...
2024-04-20 前端开发问题
5

“数组中的每个孩子都应该有一个唯一的 key prop"仅在第一次呈现页面时
quot;Each child in an array should have a unique key propquot; only on first time render of page(“数组中的每个孩子都应该有一个唯一的 key prop仅在第一次呈现页面时)...
2024-04-20 前端开发问题
5