在我的扩展程序中,我需要在单击工具栏图标时执行操作。但是,涉及到很多脚本和样式表,所以我想避免使用简单的“内容脚本”,因为这些脚本总是被加载到用户访问的每个页面中,从而减慢了浏览器的速度。相反,我想在单击按钮后才注入脚本。
文档只说以下内容:
如果您需要命令[即,单击工具栏按钮]以在注入的脚本中启动操作,请在全局HTML页面或扩展栏中响应该命令并向脚本发送消息。
在Chrome中,您可以使用chrome.tabs.executeScript()
在Firefox中,您可以使用tabs.activeTab.attach()
你是如何在Safari中完成的?
答案 0 :(得分: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);