問(wèn)題描述
我正在開發(fā)一個(gè)需要將文本插入到 contenteditable="true"
div 的應(yīng)用程序(準(zhǔn)確地說(shuō)是基于 Draftjs
的文本字段).
I'm working on an application which needs to insert text into a contenteditable="true"
div (a Draftjs
based textfield to be precise).
現(xiàn)在我知道 Draft.js 使用 react 并且應(yīng)該以這種方式使用它,但在這種情況下,應(yīng)用程序已經(jīng)存在,這是一個(gè)可以使用它的第三方電子應(yīng)用程序.
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 上的內(nèi)聯(lián)通知回復(fù),因此我需要將該回復(fù)文本粘貼到 draftJS 字段中,但是,當(dāng)我這樣做時(shí):
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');
它拋出一個(gè)錯(cuò)誤:
我能夠使用:
const event = document.createEvent('TextEvent');
event.initTextEvent('textInput', true, true, window, 'message', 0, locale);
但如果消息包含表情符號(hào),此 API 已棄用且無(wú)法正常工作.
but this API is deprecated and doesn't work properly if the message contains an emoji.
有什么方法可以做到這一點(diǎn)不會(huì)導(dǎo)致錯(cuò)誤?我發(fā)現(xiàn)應(yīng)該替換 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.
要使用它,您只需轉(zhuǎn)到 https://draftjs.org/ 并在chrome 開發(fā)工具.
To play around with it you can just go to https://draftjs.org/ and play with it in chrome dev tools.
我真的很感激這里的一些幫助,因?yàn)槲也恢涝撛趺醋霾拍茏屗ぷ髁?另外,我知道人們是 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).
請(qǐng)注意:我沒(méi)有使用react,我要修改的輸入字段(draftjs)正在使用react,我想使用本機(jī)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:
對(duì)于遇到此問(wèn)題的其他人,我想將文本插入 Facebook Messenger 文本字段(使用 Draftjs).
For anyone else coming across this issue, I wanted to insert text into the Facebook messenger text field (which uses Draftjs).
我設(shè)法找到了一個(gè)可行的解決方法.它確實(shí)使用了已棄用的 API (event.initTextEvent
),但這是我發(fā)現(xiàn)的唯一可行的方法,即使使用表情符號(hào)也是如此.如果您對(duì)此有更好的解決方案,請(qǐng)發(fā)布答案.它的工作原理是這樣的:
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 中插入一個(gè)占位符值,然后將該文本替換為:
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 中測(cè)試:版本 71.0.3578.98
推薦答案
雖然這個(gè)問(wèn)題是很久以前提出的,@JoniVR 找到了解決方法,但這可能對(duì)其他人有所幫助.
Although the question was asked a long ago and @JoniVR found a workaround, this may help someone else.
我在開發(fā)擴(kuò)展程序時(shí)也遇到了類似的問(wèn)題.我還嘗試了方法 document.execCommand('insertText', false, text).它在 LinkedIn 上有效,但在 Facebook 上無(wú)效.它在錯(cuò)誤的節(jié)點(diǎn)中插入文本.雖然 document.execCommand API 在某些地方有效,但它是現(xiàn)在已經(jīng)過(guò)時(shí)了.
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.
對(duì)于 Facebook 和任何其他使用 drafjs 編輯器的網(wǎng)站,我們需要使用 dataTransfer 和 clipBoardEvent APIs讓draftjs認(rèn)為文本被粘貼并進(jìn)行相應(yīng)處理.
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();
}
如果需要更多信息,請(qǐng)檢查此 鏈接.
Check this link in case more info needed.
這篇關(guān)于使 document.execCommand('insertText', false, 'message') 與 Draftjs 一起使用?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!