1

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

文档只说以下内容:

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

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

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

你如何在 Safari 中做到这一点?

4

1 回答 1

9

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

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

文档在这里

但是,请注意,这些方法不会在您调用它们时将内容注入到任何已经存在的选项卡中。因此,它们可能不适合您的用例。您可以使用其中一种方法,然后重新加载选项卡,但您可能不希望这样做,因为用户体验不和谐。

相反,您可能需要使用这样的技术:将一个非常轻量级的内容脚本注入到每个页面中,其唯一的工作是侦听来自扩展的全局页面的消息,并在收到指示时创建适当的<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);
于 2013-06-14T14:32:52.727 回答