ava*_*he1 4 javascript google-chrome-extension
我的扩展程序有一个包含项目的上下文菜单。我希望它做的是:当我右键单击一个editablehtml 元素(例如 input 或 textarea),然后选择并单击菜单中的一个项目时 - 由我的扩展定义的一些值被输入到输入中。
现在我已经意识到,与document.activeElement.value = myValue.
通过简单的输入,它可以正常工作。
当有自定义onChange事件处理的输入时,问题就开始了,例如日历或电话输入,或货币输入 - 以某种方式转换用户输入。
由于我直接在元素上设置一个值 - 处理逻辑被省略,这会导致各种问题。
由于 javascript 不允许类似 KeySend 的功能 - 我在这里有什么选择?
我曾考虑过像 Puppeteer 或 Cypress 这样的测试工具 - 但它们似乎都不能打包到扩展中。Puppeteer 确实有这样的选项,但它仍然需要一个运行的节点实例来连接。而且我希望我的扩展程序仅在客户端并分发在 Chrome 网上商店中 - 所以我不能要求我的用户运行启动节点服务器。
Joh*_* Wu 11
因为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");
}
}
Run Code Online (Sandbox Code Playgroud)
下面的代码只能在普通网站上起作用,但对于强网站(例如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);
}
Run Code Online (Sandbox Code Playgroud)
wOx*_*xOm 10
有一个内置的 DOM 方法document.execCommand。
如果是扩展,请在内容脚本中使用此代码。
请注意,execCommand 在 2020 年被标记为过时,但它会在可预见的未来工作,因为新的编辑 API 规范尚未完成,并且知道这些事情通常移动多慢,可能还需要 5-20 年。
// 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
Run Code Online (Sandbox Code Playgroud)
它模仿用户对当前聚焦的 DOM 元素的物理输入,因此将触发所有必要的事件(如beforeinput, input),并将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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
964 次 |
| 最近记录: |