2015-11-08 52 views
0

(我將把內容腳本cs.js和background.js爲ba.js的ContextMenu處理

場景:

oncontextmenu點擊,我需要確定頁面的url及其被阻止的狀態,並將其發送到ba.js。代碼(cs.js):

var triggered = false; 

window.oncontextmenu = function(event){ 
    if(triggered) return; 

    chrome.runtime.sendMessage({ 
     url: window.location.href, 
     blocked: isBlocked 
    }, function(response){ // after work has been done 
     triggered = true;   
     triggerEvent(window, "contextmenu", event); // line A 
     triggered = false; // line C 
    }); 

    return false; // line B 
}; 

的問題是,到時候我得到的迴應,上下文菜單已經被顯示給用戶沒有我所需的信息(因爲我沒有得到迴響應,這意味着ba.js沒有完成chrome.contextMenus.update呼叫還)因此,作爲一個解決方案,我有:

  1. 返回false以防止它被示出(B線)
  2. 使用一個trigger布爾值,以確保消息不再次發送,當我triggerEvent A線(全球)
  3. 然後重新上線C.

trigger布爾但是這種方法是行不通的。因此,我需要一種方法來:

在上下文菜單操作,發送從有關cs.js消息ba.js基礎上只提供給cs.js和某些參數更新的上下文菜單然後,只有在收到消息後,才能向用戶顯示上下文菜單。

注:我已經使用chrome.tabs.onUpdated和其他朋友(這樣我就可以檢測用戶在其上存在的當前頁面,因此獲得必要的參數我)試過了,但是,我不能讓它也可以使用它們。

ba.jsonMessage

chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse){ 
    if(typeof msg.url !== undefined){ 
     url = msg.url; // global 

     isBlocked = msg.blocked; // global 
     action = isBlocked ? "Unblock" : "Block"; // global 

     chrome.contextMenus.update("blockSite", { // update action 
      title: action + " this site" 
     }); 

     sendResponse("done"); // send confirmation 
    } 
}); 

triggerEvent代碼:

function triggerEvent(node, eventName, obj){ 
    var ev = new CustomEvent(eventName, obj || {}); 

    node.dispatchEvent(ev); 
} 

UPDATE

所以,我用onActivated這一次,它從一個工作得很好,除了大發行e:

如果我打開一個新選項卡,然後單擊網站平鋪/類型網站地址並打開該網站。然後,onActivated偵聽器不會觸發(這當然是顯而易見的)。 我無法使用onUpdated,因爲無論何時更新iframe,即使在當前未處於活動狀態的頁面中,也會觸發。

我能做些什麼來糾正這個錯誤?

+0

我不知道很多關於Chrome擴展程序,也無法左右你試圖實現什麼,但是你不能在contextmenu事件之前做這個請求嗎?然後** cs.js **在事件觸發時已經知道'isBlocked'的值。我的意思是,你似乎在尋找'location.href'來確定'isBlocked',所以你應該能夠在加載時獲得它。也許你可以在後臺(我猜是某種數據庫或某種東西)和頁面上更新它兩次。 – Kaiido

+0

@Kaiido如果我在上下文菜單事件之前發送消息給** ba.js ** *,那麼只要頁面加載完成,它就會發送一條消息,而不是當它聚焦時。 –

+1

您所要求的是不可能的(但?),但已被提議作爲功能請求:[問題60758:允許在呈現之前使用特定於上下文的信息更新contextMenus](https://code.google。 COM/p /鉻/問題/細節?ID = 60758)。 –

回答

2

您不能以實用的方式在Chrome中觸發內置的上下文菜單。因爲這是Chrome用來授予某些臨時權限(如activeTab)的用戶手勢之一。

使用tabs.onActivatedtabs.onUpdated事件偵聽器跟蹤活動選項卡中的更改並相應地更新上下文菜單。

  • 持續的背景頁面(默認模式):

    var activeTabId; 
    
    chrome.tabs.onActivated.addListener(function(info) { updateContextMenu(info.tabId) }); 
    
    chrome.tabs.onUpdated.addListener(function(tabId, info, tab) { 
        if (tabId == activeTabId) { 
         updateContextMenu(tabId); 
        } 
    }); 
    
    function updateContextMenu(tabId) { 
        activeTabId = tabId; 
        chrome.tabs.get(tabId, function(tab) { 
         var isBlocked = checkBlockedState(tab.url); 
         chrome.contextMenus.update("blockSite", { 
          title: (isBlocked ? "Unblock" : "Block") + " this site" 
         }); 
        }); 
    } 
    
  • 活動頁面("persistent" : false):

    chrome.tabs.onActivated.addListener(function(info) { updateContextMenu() }); 
    
    chrome.tabs.onUpdated.addListener(function(tabId, info, tab) { 
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { 
         if (tabs[0].id == tabId) { 
          updateContextMenu(); 
         } 
        }); 
    }); 
    
    function updateContextMenu() { 
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { 
         var isBlocked = checkBlockedState(tabs[0].url); 
         chrome.contextMenus.update("blockSite", { 
          title: (isBlocked ? "Unblock" : "Block") + " this site" 
         }); 
        }); 
    } 
    
+0

謝謝你的回答。請看我更新的問題。 –

+0

查看最新的答案。 – wOxxOm

+0

哇!好的解決方案!非常感謝!只有一個問題:爲什麼需要兩個單獨的頁面?就像一個持久的和其他非持久的?兩者似乎都做同樣的事情... –