【问题标题】:Add event listener to Chrome extension for new tabs and windows为新标签页和窗口添加事件监听器到 Chrome 扩展
【发布时间】:2017-01-28 07:34:25
【问题描述】:

chrome 扩展在新选项卡中打开,并在加载时获取打开的窗口和选项卡的信息,但我必须刷新它才能打开任何新的选项卡或窗口。

这是清单文件中的代码:

 "background": {
    "page": "background.html",
    "persistent": true
    },
"content_security_policy": "script-src 'self' 'unsafe-eval' https://code.jquery.com; object-src 'self'",

"permissions": [
  "contextMenus",
  "notifications",
  "tabs",
  "clipboardWrite",
  "unlimitedStorage"
],
"content_scripts": [{
        "matches": ["*://*/*"],
        "js": ["jan13.js", "background.js"],
        "css": ["jan13.css"]
        }

background.html 页面调用两个脚本“jan13.js”和“background.js”。

<!DOCTYPE html>
<html>
<head></head>
<body>
<script src="jquery.min.js"></script>
<script src="background.js"></script>
<script src="jan13.js"></script>
</body>
</html>

“background.js”文件只是在自己的选项卡中打开扩展,如下所示:

chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.create({'url': chrome.extension.getURL('popup.html'), 'selected': true});
});

然后“jan13.js”完成所有实际工作:

$(document).ready(function() {

 chrome.windows.getAll({populate:true},function(windows){

    for (i=0; i < windows.length; i++) {
        a = (i+1);

        $('<div/>', {
            id: 'win'+a,
        }).attr('class', 'box1').html("<h3>Window"+a+"</h3>").appendTo('.container');

        windows[i].tabs.forEach(function(tab){

            var favic = tab.favIconUrl;

            var link = $('<a>', {
                text:tab.title,
                href:tab.url,
                }); 
           link.attr("target", "_blank");
           $('#win'+a).append(link); 

            $(link).prepend($('<img>', {id:'favic', src: favic}));
        });
    };

    $('<div/>').attr('class', 'button').text("Toggle").appendTo('.box1');

    $('.button').click(function() {
        var b = $(this).parent().closest('div');
        $(b[0]).toggleClass("box1a");
    });       
  });
});

我已尝试将此代码放在“background.js”和/或“background.html”中:

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    $.getScript("jan13.js");
});
chrome.tabs.onCreated.addListener(function(tab) {     
    $.getScript("jan13.js");
});

但我收到以下错误:

拒绝执行内联脚本,因为它违反了以下内容安全策略指令:“script-src 'self' 'unsafe-eval' https://code.jquery.com”。启用内联执行需要“unsafe-inline”关键字、哈希(“sha256-VCQyoq7QBv4UrBn0VODLZE8rJZdjIt7Kb3PziCSqIXM=”)或随机数(“nonce-...”)。

我也经常收到此错误:

Uncaught ReferenceError: $ is not defined

但它不会阻止扩展程序运行。

当我尝试像这样将“background.js”和/或“jan13.js”放入清单时:

"background": {
    "scripts": ["background.js", "jan13.js"],
    "persistent": true
    },

扩展程序根本没有打开。我单击工具栏图标,没有任何反应。这就是为什么我把它放在“background.html”中。这对我来说似乎很复杂,但这是我让它发挥作用的唯一方法。

最初的问题是如何添加 eventListener 以便扩展程序自动打开任何新选项卡或窗口?如果我刷新页面,它会起作用。

编辑:将清单文件更改为:

{
"manifest_version": 2,
"name": "Session Sync",
"version": "0.1.0",
"description": "Sync browser sessions",
"author": "Mischa Bertrand-Chetty",
"browser_action": {
    "default_title": "Starting Session Sync..."
    },
"background": {
    "scripts": ["jquery.min.js","background.js", "jan13.js"],
    "persistent": true
    },
"content_security_policy": "script-src 'self' 'unsafe-eval' https://code.jquery.com; object-src 'self'",

"permissions": [
  "contextMenus",
  "notifications",
  "tabs",
  "clipboardWrite",
  "unlimitedStorage"
],
"content_scripts": [{
        "matches": ["*://*/*"],
        "css": ["jan13.css"]
        }
    ],
"incognito": "spanning"
}

好消息是我不再收到参考错误。然而,原来的问题,它不听任何新的标签或窗口仍然存在。我仍然需要刷新页面才能获得新的标签和窗口。

【问题讨论】:

  • 下载 jquery 文件存储本地文件夹并在您的扩展中提供下载文件的参考。
  • 我做到了...这就是为什么我在“background.html”和主 html 文件中引用“jquery.min.js”的原因。
  • 您是否有理由使用 background.html 而不仅仅是 "background": {"scripts": ["jquery.min.js","background.js", "jan13.js"],"persistent": true}
  • 您正在使用 background.jsjan13.js 作为 both 后台脚本和内容脚本。这几乎总是一个坏主意™。在这种情况下,它肯定是,因为 A) 两个脚本都使用内容脚本不可用的 API,并且 B) 你尝试在 jan13.js 中使用 jQuery,不要在 content_script 条目中加载 jQuery。
  • 刚刚意识到它以前不起作用,因为我也没有将“jquery.min.js”添加到后台脚本中。我已经按照你描述的方式完成了。但是当我想要更新它时,我仍然需要刷新它。

标签: javascript jquery google-chrome-extension


【解决方案1】:

将注入 DOM 元素的代码移动到命名函数中,以便您可以从选项卡的 onCreated 和 onUpdated 处理程序中调用它,而不是重新加载脚本。您可能也不希望每次都重新加载整个脚本并完全重新扫描窗口:您可能希望为每个更新/创建的选项卡执行一次。那么您将不需要 CSP 规则,因为您不会重新加载脚本。

在 background.js 中,放置你的函数和调用它的处理程序:

function scanTabs() {
  chrome.windows.getAll({populate: true}, function(windows) {
..etc..
}
$(document).ready(scanTabs);
chrome.tabs.onUpdated.addListener(scanTabs);
chrome.tabs.onCreated.addListener(scanTabs);

你根本不需要jan13.js

希望这足以让您走上正轨。

【讨论】:

  • 所以我会将“jan13.js”中“$document.ready(function)”之后的所有内容放入“function myFunction{ .....};”中?如何从“background.js”调用该函数?我正在尝试给我“未定义的功能”,只是加载一个空白选项卡。
  • 感谢@Tim Dierks 帮了大忙。现在我只需要让它不重复所有内容 4 次。我想我必须替换我的 forEach 函数,因为显然没有好的方法可以打破它。而且我不认为在 for 循环中放置“if”语句是好的做法或有效的。目前它通过整个函数 4 次,我只是设法不让它重复创建一个新的“win+a div”,但它仍然通过相同的选项卡。
猜你喜欢
  • 2013-11-30
  • 2020-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-27
  • 2017-08-13
  • 1970-01-01
  • 2023-01-10
相关资源
最近更新 更多