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

sff*_*ffc 1 javascript safari-extension

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

文档只说以下内容:

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

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

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

你是如何在Safari中做到的?

chu*_*ter 9

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

safari.extension.addContentScript
safari.extension.addContentScriptFromURL
safari.extension.addContentStyleSheet
safari.extension.addContentStyleSheetFromURL
Run Code Online (Sandbox Code Playgroud)

文档在这里.

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

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

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

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

在全局页面中:

safari.application.addEventListener('command', function (evt) {
    safari.application.activeBrowserWindow.activeTab.page.dispatchMessage(evt.command);
}, false);
Run Code Online (Sandbox Code Playgroud)

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

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);
Run Code Online (Sandbox Code Playgroud)