javascript 如何在自定义处理的输入字段中输入数据?

stszievb  于 2023-02-28  发布在  Java
关注(0)|答案(2)|浏览(177)

我的扩展有一个包含项目的上下文菜单。我希望它执行以下操作:当我右键单击editable HTML元素(例如input或textarea),然后选择并单击菜单中的某个项目时,由我的扩展定义的某个值将被输入到输入中。
现在我已经意识到:

document.activeElement.value = myValue

工作正常与简单的输入。
当有一个带有自定义onChange事件处理的输入时,问题就开始了,例如日历或电话输入,或者货币输入--它们以某种方式转换用户输入。
因为我直接在元素上设置了一个值-处理逻辑被忽略了,这会导致各种各样的问题。
由于JavaScript不允许类似KeySend的特性,我在这里有什么选择?
我曾经考虑过测试Puppeteer或Cypress这样的工具,但它们似乎都不能打包成一个扩展。Puppeteer确实有这样的选项,但它仍然需要一个节点示例来连接。我希望我的扩展是完全客户端的,并在Chrome网络商店中分发-所以我不能要求我的用户启动一个节点服务器。

wn9m85ua

wn9m85ua1#

有一个内置的DOM方法document.execCommand
如果是扩展,请在content script中使用此代码。

// some.selector may be `input` or `[contenteditable]` for richly formatted inputs
const el = document.querySelector('some.selector');
el.focus();
document.execCommand('insertText', false, 'new text');
el.dispatchEvent(new Event('change', {bubbles: true})); // usually not needed

它模拟用户在当前焦点DOM元素中的物理输入,以便在isTrusted字段设置为true的情况下触发所有必要的事件(如beforeinputinput)。在某些页面上,change事件应如上所示额外调度。

您可能希望选择当前文本以完全替换它,而不是追加:

replaceValue('some.selector', 'new text');

function replaceValue(selector, value) {
  const el = document.querySelector(selector);
  if (el) {
    el.focus();
    el.select();
    if (!document.execCommand('insertText', false, value)) {
      // Fallback for Firefox: just replace the value
      el.value = 'new text';
    }
    el.dispatchEvent(new Event('change', {bubbles: true})); // usually not needed
  }
  return el;
}

请注意,尽管execCommand在2020年被标记为过时,但它在可预见的未来仍将工作,因为新的编辑API规范尚未完成,而且知道此类事情通常进展缓慢,可能还需要5-20年。

vfh0ocws

vfh0ocws2#

由于document.execCommand()已经过时,我现在使用下面的代码,它运行良好:

function imitateKeyInput(el, keyChar) {
  if (el) {
    const keyboardEventInit = {bubbles:false, cancelable:false, composed:false, key:'', code:'', location:0};
    el.dispatchEvent(new KeyboardEvent("keydown", keyboardEventInit));
    el.value = keyChar;
    el.dispatchEvent(new KeyboardEvent("keyup", keyboardEventInit));
    el.dispatchEvent(new Event('change', {bubbles: true})); // usually not needed
  } else {
    console.log("el is null");    
  }
}

下面的代码只能在普通网站上工作,但对强大网站(如Facebook)无效。

function fireKeyEvent(el, evtType, keyChar) {
  el.addEventListener(evtType, function(e) {el.value += e.key;}, false);
  el.focus();
  const keyboardEventInit = {bubbles:false, cancelable:false, composed:false, key:keyChar, code:'', location:0};
  var evtObj = new KeyboardEvent(evtType, keyboardEventInit);
  el.dispatchEvent(evtObj);
}

相关问题