如何检测Gmail中的键盘事件
How can I detect keyboard events in Gmail
我正在编写一个浏览器扩展,它需要将处理程序附加到所有页面上的keyup
和keydown
事件。我可以很好地使用以下内容脚本代码。
document.addEventListener("keydown",keyDown, true);
document.addEventListener("keyup", keyUp, true);
不过我无法在Gmail中使用它。特别是,在撰写新电子邮件正文时,我无法让它发挥作用。它在我测试过的其他地方都有效。我认为问题是因为Gmail在所有键盘事件上都调用stopPropagation
,但很难调试它们的最小化代码。我认为将第三个参数设置为true
会导致在CAPTURE_PHASE
期间捕获事件,但这不起作用。
如何在Gmail中使用Google Chrome内容脚本撰写新正文时捕获keyup
和keydown
事件?
编辑:
通过将"all_frames": true,
添加到清单中,我已经确保了我的内容脚本被注入到DOM的所有iframe中。我甚至尝试过使用以下代码:
document.addEventListener("DOMNodeInserted", function (event) {
if(event.type === "DOMNodeInserted") {
if(event.srcElement.nodeName === "IFRAME") {
console.log(event.srcElement.nodeName + " iframe detected");
event.srcElement.addEventListener("keydown", function(kevent) {
document.dispatchEvent(kevent);
}, true);
event.srcElement.addEventListener("keyup", function(kevent) {
document.dispatchEvent(kevent);
}, true);
}
}
},true);
这仍然不能解决Gmail的问题。
您的代码不起作用,因为event.srcElement
引用的是<iframe>
元素,而不是它的内容。要访问其内容文档,您必须等待加载帧(onload
或轮询),然后使用frame.contentDocument
访问帧。
从Chrome 37.0.1995.0开始,您还可以使用match_about_blank
(带all_frames)在about:blank
帧中插入一个内容脚本,该脚本捕获事件并将其发送给父内容脚本。
以下是原始想法的实现示例(使用轮询):
manifest.json
:的相关部分
"content_scripts": [{
"matches": ["*://mail.google.com/*"],
"js": ["contentscript.js"],
"run_at": "document_end"
}],
contentscript.js
function keyDown(e) {console.log(e.which);}; // Test
function keyUp(e) {console.log(e.keyCode);}; // Test
(function checkForNewIframe(doc) {
if (!doc) return; // document does not exist. Cya
// Note: It is important to use "true", to bind events to the capturing
// phase. If omitted or set to false, the event listener will be bound
// to the bubbling phase, where the event is not visible any more when
// Gmail calls event.stopPropagation().
// Calling addEventListener with the same arguments multiple times bind
// the listener only once, so we don't have to set a guard for that.
doc.addEventListener('keydown', keyDown, true);
doc.addEventListener('keyup', keyUp, true);
doc.hasSeenDocument = true;
for (var i = 0, contentDocument; i<frames.length; i++) {
try {
contentDocument = iframes[i].document;
} catch (e) {
continue; // Same-origin policy violation?
}
if (contentDocument && !contentDocument.hasSeenDocument) {
// Add poller to the new iframe
checkForNewIframe(iframes[i].contentDocument);
}
}
setTimeout(checkForNewIframe, 250, doc; // <-- delay of 1/4 second
})(document); // Initiate recursive function for the document.
请注意,我使用了轮询而不是DOM突变事件,因为后者大大降低了性能。
这可能有助于
如何在gmail 中收听键盘事件
DOM冒泡从窗口开始,所以您需要将侦听器连接到那里,并指定第三个参数true来指示捕获阶段,这实际上是第一个事件阶段wOxxOm
根据你的代码,它可能是这样的:
window.addEventListener("keydown",keyDown, true);
window.addEventListener("keyup", keyUp, true);
- Vue键盘事件未启动
- Bootstrap 3键盘对默认键盘事件没有反应
- 是否可以使用JavaScript创建计算机宏(键盘事件等)
- JavaScript 键盘事件和比较
- 虚拟键盘事件
- 如何在 LimeJS javascript for html5 中处理键盘事件
- 调度键盘事件不'不能在JavaScript中工作
- 在谷歌地图上收听键盘事件
- 无法在鳄梨酱iframe中获取键盘事件
- 扩展浏览器以处理Apple键盘事件
- 用防油键或防篡改键触发键盘事件
- 如何使用自定义键盘事件和keyCode更改输入/textarea值
- 如何在svg上收听键盘事件
- 如何存储鼠标&键盘事件和值
- 键盘事件代码
- 国际键盘如何处理 JavaScript 键盘事件
- 来自键盘事件的 JS 读取变量
- 如何在 CodeMirror 中触发键盘事件
- 具有离子形式的键盘事件
- JavaScript 键盘事件未触发