【问题标题】:Enter data into a custom-handled input field在自定义处理的输入字段中输入数据
【发布时间】:2020-01-12 17:09:10
【问题描述】:

我的扩展程序有一个包含项目的上下文菜单。我想做的是:当我右键单击 editable html 元素(例如 input 或 textarea),然后选择并单击菜单中的一个项目时——我的扩展程序定义的一些值被输入到输入中.

现在我已经意识到document.activeElement.value = myValue.
只需简单的输入就可以正常工作。

当有带有自定义 onChange 事件处理的输入时出现问题,例如日历或电话输入,或货币输入 - 以某种方式转换用户输入。
由于我直接在元素上设置了一个值 - 处理逻辑被省略了,这会导致各种问题。

由于 javascript 不允许类似 KeySend 的功能 - 我有什么选择?

我曾考虑过像 Puppeteer 或 Cypress 这样的测试工具 - 但它们似乎都不能打包成扩展。 Puppeteer 确实有这样的选项,但它仍然需要运行节点实例才能连接。而且我希望我的扩展程序完全是客户端的并在 Chrome 网上商店中分发 - 所以我不能要求我的用户启动节点服务器。

【问题讨论】:

  • @wOxxOm 您可能应该将其转换为答案,以便将其标记为已解决。

标签: javascript google-chrome-extension


【解决方案1】:

有一个内置的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 元素,因此所有必要的事件都将被触发(如 beforeinputinput),并将 isTrusted 字段设置为 true。在某些页面上,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 年。

【讨论】:

    【解决方案2】:

    @wOxxOm,非常感谢! 我用你的代码解决了困扰我很久的问题。我用谷歌搜索了很多代码和文章近一个月。 它适用于 Facebook 和许多强大的网站。

    因为 execCommand 已经过时,我尝试下面的代码运行良好,包括 Facebook。

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

    以下代码只适用于普通网站,对强网站无效。

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

    【讨论】:

    猜你喜欢
    相关资源
    最近更新 更多