【问题标题】:pass dom element from background script to chrome.tabs.executeScript将 dom 元素从后台脚本传递给 chrome.tabs.executeScript
【发布时间】:2013-08-22 18:07:01
【问题描述】:

当从我的后台脚本中单击上下文菜单时,我试图将活动的 dom 元素传递给通过 chrome.tabs.executeScript 调用的脚本。我可以很好地传递布尔值和字符串,但是当我传递 dom 元素时总是会出错。我开始认为这是不可能的。

//doScripts function called from browser action
chrome.browserAction.onClicked.addListener(function(tab) {
    doScripts(true, null);
});

//doScripts function called from context menu click
function getClickHandler(info, tab) {
    var currTarg = document.activeElement;
    console.log("currTarg = " + currTarg);
    doScripts(false, currTarg); 
}

//i reference doingBrowserAction and contextTarg in myscript.js
function doScripts(context, targ){
    chrome.tabs.executeScript(null, {code: "var doingBrowserAction = "+context+"; var contextTarg = "+targ+";"}, function(){
        chrome.tabs.executeScript(null, {file: "js/myscript.js"}, function(){
        //all injected
        });
    });
}
//setup context menu
chrome.contextMenus.create({
  "title" : "DESTROY!",
  "type" : "normal",
  "contexts" : ["page","selection","link","editable","image","video","audio"],
  "onclick" : getClickHandler
});

我在 myscript.js 中引用了 doingBrowserAction 和 contextTarg。我知道我正在尝试做的事情是可能的,因为 adblock 扩展可以做到这一点,但很难弄清楚如何做。提前致谢。

【问题讨论】:

    标签: google-chrome google-chrome-extension


    【解决方案1】:

    您无法从后台页面直接引用内容脚本的 DOM 元素,因为后台页面在扩展程序的进程中运行,而内容脚本在选项卡的进程中运行。另见https://code.google.com/p/chromium/issues/detail?id=39507

    背景页面中的document.activeElement 属性指的是背景页面文档中的活动元素。可以想象,这个值是很没用的。

    如果查询当前右键元素的状态,在内容脚本中绑定一个事件。在下一个示例中,我选择了contextmenu 事件,因为上下文菜单也可以通过键盘打开。

    此示例添加了一个上下文菜单选项,用于从文档中删除最后一个活动元素。

    // content script
    var lastElementContext;
    document.addEventListener('contextmenu', function(event) {
        lastElementContext = event.target;
    }, true);
    chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
        if (lastElementContext && lastElementContext.parentNode) {
            lastElementContext.parentNode.removeChild(lastElementContext);
            lastElementContext = null;
        }
    });
    

    后台脚本:

    chrome.contextMenus.create({
        title: 'DESTROY!',
        contexts: ['page', 'link', 'editable', 'image', 'video', 'audio'],
        onclick: function(info, tab) {
            chrome.tabs.sendMessage(tab.id, 'doDestroy');
        }
    });
    

    【讨论】:

    • 工作得很好,现在有什么办法可以将 lastElementContext 传递给 myscript.js,还是我必须从内容脚本中调用所有脚本?
    • @user2503648 同一个扩展的所有内容脚本共享同一个命名空间。你可以从myscript.js引用lastElementContext,前提是我展示的代码在你插入内容脚本之前执行。
    猜你喜欢
    • 2012-10-24
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多