Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 阻止上下文菜单启动,直到内容脚本返回响应_Javascript_Google Chrome_Google Chrome Extension - Fatal编程技术网

Javascript 阻止上下文菜单启动,直到内容脚本返回响应

Javascript 阻止上下文菜单启动,直到内容脚本返回响应,javascript,google-chrome,google-chrome-extension,Javascript,Google Chrome,Google Chrome Extension,(我将内容脚本称为cs.js,background.js称为ba.js) 场景: oncontextmenu单击,我需要确定页面的url及其阻止状态,并将其发送到ba.js。代码(cs.js): 问题是,当我得到响应时,上下文菜单已经显示给用户,而没有显示我想要的消息(因为我没有得到响应,这意味着ba.js尚未完成chrome.contextMenus.update调用),因此,作为解决方案,我有: 返回false以防止其显示(第B行) 使用触发器布尔值来确保在a行的I触发器事件(全局)时不会再

(我将内容脚本称为cs.js,background.js称为ba.js

场景:

oncontextmenu
单击,我需要确定页面的url及其阻止状态,并将其发送到ba.js。代码(cs.js):

问题是,当我得到响应时,上下文菜单已经显示给用户,而没有显示我想要的消息(因为我没有得到响应,这意味着ba.js尚未完成
chrome.contextMenus.update
调用),因此,作为解决方案,我有:

  • 返回
    false
    以防止其显示(第B行)
  • 使用
    触发器
    布尔值来确保在a行的I
    触发器事件
    (全局)时不会再次发送消息
  • 然后在C行重置
    触发器
    布尔值
  • 然而,这种方法不起作用。因此,我需要一种方法:

    在上下文菜单操作中,从相关的cs.js向ba.js发送一条消息,以根据仅对cs.js可用的某些参数更新上下文菜单,然后仅在收到返回的消息后,向用户显示上下文菜单。

    注意:我已经尝试过使用
    chrome.tabs.onUpdate
    和其他朋友(这样我就可以检测到用户所在的当前页面,从而自己获得必要的参数),但是,我无法使用它们来实现这一点

    ba.js
    onMessage

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

    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
    };
    
    因此,我使用了激活的
    ,这一次效果非常好,除了一个大问题:

    如果我打开一个新选项卡,然后单击站点平铺/键入站点地址,站点将打开。然后,激活的
    侦听器不会启动(这当然是显而易见的) 我不能为此使用
    onUpdated
    ,因为它会在iframe更新时触发,即使在当前不活动的页面中也是如此


    如何更正此错误?

    您不能实际触发Chrome中的内置上下文菜单。因为这是Chrome用来授予某些临时权限的用户手势之一,比如
    activeTab

    使用
    tabs.on activated
    tabs.on updated
    事件侦听器跟踪活动选项卡中的更改,并相应地更新上下文菜单

    • 持久后台页面(默认模式):

    • 事件页(
      “持久”:false
      ):


    我不太了解chrome扩展,也不知道您想要实现什么,但您不能在contextmenu事件之前完成此请求吗?然后cs.js将在事件触发时已经知道
    isBlocked
    的值。我的意思是,似乎您正在查找
    位置。href
    以确定
    已阻止
    ,因此您应该能够在加载时获取它。也许你可以在后台(我猜是某种数据库什么的)和页面上更新它两次。@kaido如果我在上下文菜单事件之前向ba.js发送消息,那么它会在页面刚加载时发送消息,而不是在页面聚焦时发送消息。你所要求的是不可能的(现在?),但已作为功能请求提出:。
    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"
            });
        });
    }
    
    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"
            });
        });
    }