Javascript Safari扩展:如何仅在单击工具栏按钮后注入内容脚本?
在我的扩展中,我需要在单击工具栏图标时执行操作。然而,其中涉及到很多脚本和样式表,因此我希望避免使用普通的“内容脚本”,因为这些脚本总是会加载到用户访问的每个页面中,从而降低其浏览器的速度。相反,我只想在单击按钮后注入脚本 这些文件只说了以下几点: 如果需要命令[即,工具栏按钮单击]来启动注入脚本中的操作,请在全局HTML页面或扩展栏中响应该命令,并向脚本发送消息 在Chrome中,您可以使用 在Firefox中,您可以使用Javascript Safari扩展:如何仅在单击工具栏按钮后注入内容脚本?,javascript,safari-extension,Javascript,Safari Extension,在我的扩展中,我需要在单击工具栏图标时执行操作。然而,其中涉及到很多脚本和样式表,因此我希望避免使用普通的“内容脚本”,因为这些脚本总是会加载到用户访问的每个页面中,从而降低其浏览器的速度。相反,我只想在单击按钮后注入脚本 这些文件只说了以下几点: 如果需要命令[即,工具栏按钮单击]来启动注入脚本中的操作,请在全局HTML页面或扩展栏中响应该命令,并向脚本发送消息 在Chrome中,您可以使用 在Firefox中,您可以使用 如何在Safari中实现这一点?您可以使用以下四种方法有条件地将内容注
如何在Safari中实现这一点?您可以使用以下四种方法有条件地将内容注入页面:
safari.extension.addContentScript
safari.extension.addContentScriptFromURL
safari.extension.addContentStyleSheet
safari.extension.addContentStyleSheetFromURL
但是,请注意,在调用这些方法时,它们不会将内容注入任何现有选项卡中。因此,它们可能不适合您的用例。您可以使用其中一种方法,然后重新加载选项卡,但由于用户体验不和谐,您可能不希望这样做
相反,您可能需要使用这样一种技术:拥有一个非常轻量级的内容脚本,该脚本将被注入到每个页面中,其唯一任务是侦听来自扩展的全局页面的消息,并在收到指示时为要注入的内容创建适当的
和
或
元素。然后,单击工具栏按钮时,让全局页面将适当的消息传递给内容脚本,可能包括所需内容的URL
这种方法的一个缺点是,注入的脚本(通过创建
标记添加的脚本)将无法直接与全局页面或扩展的其他部分通信。如果您需要他们交流,他们需要使用window.postMessage
或其他技术
这里有一个最小的例子。假设您的扩展有一个工具栏项,它发出命令“injectcontent”
在全局页面中:
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);
您可以使用以下四种方法有条件地将内容注入页面:
safari.extension.addContentScript
safari.extension.addContentScriptFromURL
safari.extension.addContentStyleSheet
safari.extension.addContentStyleSheetFromURL
但是,请注意,在调用这些方法时,它们不会将内容注入任何现有选项卡中。因此,它们可能不适合您的用例。您可以使用其中一种方法,然后重新加载选项卡,但由于用户体验不和谐,您可能不希望这样做
相反,您可能需要使用这样一种技术:拥有一个非常轻量级的内容脚本,该脚本将被注入到每个页面中,其唯一任务是侦听来自扩展的全局页面的消息,并在收到指示时为要注入的内容创建适当的
和
或
元素。然后,单击工具栏按钮时,让全局页面将适当的消息传递给内容脚本,可能包括所需内容的URL
这种方法的一个缺点是,注入的脚本(通过创建
标记添加的脚本)将无法直接与全局页面或扩展的其他部分通信。如果您需要他们交流,他们需要使用window.postMessage
或其他技术
这里有一个最小的例子。假设您的扩展有一个工具栏项,它发出命令“injectcontent”
在全局页面中:
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);
因此,一旦安装了扩展,就不可能更改已安装扩展的网页。我的目标是告诉用户“做得好,安装了扩展”。因此,扩展glocal页面应该向网页/内容脚本发送消息,但据我所知,它没有运行。。。有什么解决办法吗?如果你想确保你的内容脚本已经加载,你可以在全局脚本中添加一些代码,强制所有选项卡重新加载。但这并不漂亮。我只需要在单击扩展工具栏时插入脚本。您能建议如何发送消息吗?新问题发布在这里->因此,一旦安装了扩展,就不可能更改已安装扩展的网页。我的目标是告诉用户“做得好,安装了扩展”。因此,扩展glocal页面应该向网页/内容脚本发送消息,但据我所知,它没有运行。。。有什么解决办法吗?如果你想确保你的内容脚本已经加载,你可以在全局脚本中添加一些代码,强制所有选项卡重新加载。但这并不漂亮。我只需要在单击扩展工具栏时插入脚本。您能建议如何发送消息吗?新问题发布在此处->