簡體   English   中英

如何在Gmail中檢測鍵盤事件

[英]How can I detect keyboard events in Gmail

我正在編寫一個瀏覽器擴展,需要將處理程序附加到所有頁面上的keyup和keydown事件。 我可以使用以下內容腳本代碼很好地工作。

document.addEventListener("keydown",keyDown, true);      
document.addEventListener("keyup", keyUp, true);

我不能讓這個在Gmail中運行。 具體來說,在編寫新電子郵件的正文時,我無法使其工作。 它將適用於我測試過的其他任何地方。 我認為問題是因為Gmail在所有鍵盤事件上調用stopPropagation但很難調試其最小化代碼。 我認為將第3個參數設置為true會導致在CAPTURE_PHASE期間捕獲事件,但這不起作用。

如何在使用Google Chrome內容腳本在Gmail中編寫新主體時捕獲keyupkeydown事件?

編輯:

通過在我的清單中添加"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或polling),然后使用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突變事件,因為后者嚴重降低了性能

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM