Safari扩展:如何在单击工具栏按钮后注入内容脚本?

时间:2013-06-13 22:46:19

标签: javascript safari-extension

在我的扩展程序中,我需要在单击工具栏图标时执行操作。但是,涉及到很多脚本和样式表,所以我想避免使用简单的“内容脚本”,因为这些脚本总是被加载到用户访问的每个页面中,从而减慢了浏览器的速度。相反,我想在单击按钮后才注入脚本。

文档只说以下内容:

  

如果您需要命令[即,单击工具栏按钮]以在注入的脚本中启动操作,请在全局HTML页面或扩展栏中响应该命令并向脚本发送消息。

在Chrome中,您可以使用chrome.tabs.executeScript()

在Firefox中,您可以使用tabs.activeTab.attach()

你是如何在Safari中完成的?

1 个答案:

答案 0 :(得分:9)

您可以使用以下四种方法有条件地将内容注入页面:

safari.extension.addContentScript
safari.extension.addContentScriptFromURL
safari.extension.addContentStyleSheet
safari.extension.addContentStyleSheetFromURL

Documentation here

但请注意,这些方法在您调用时不会将内容注入任何现有标签 。因此,它们可能不适合您的用例。您可以使用其中一种方法然后重新加载选项卡,但由于用户体验不佳,您可能不希望这样。

相反,您可能需要使用这样的技术:将一个非常轻量级的内容脚本注入到每个页面中,其唯一的工作是从扩展的全局页面侦听消息,并在指示时创建适当的要注入的内容的<script><style><link>元素。然后,当单击工具栏按钮时,让全局页面将相应的消息传递给内容脚本,可能包括所需内容的URL。

此方法的缺点是注入的脚本(您通过创建<script>标记添加的脚本)将无法直接与全局页面或扩展的其他部分进行通信。如果您需要他们进行沟通,他们需要使用window.postMessage或其他技术进行沟通。

这是一个最小的例子。假设您的扩展程序有一个工具栏项,它发出命令“inject-content”。

在全球网页中:

safari.application.addEventListener('command', function (evt) {
    safari.application.activeBrowserWindow.activeTab.page.dispatchMessage(evt.command);
}, false);

在始终注入的内容脚本中:

safari.self.addEventListener('message', function (evt) {
    if (evt.name == 'inject-content') {
        var myScriptTag = document.createElement('script');
        myScriptTag.src = safari.extension.baseURI + 'my_script.js';
        document.body.appendChild(myScriptTag);
    }
}, false);