切换页面内Angular Chrome扩展的可见性
Toggle visibility of an in-page Angular Chrome extension
我有一个bookmarklet,我迁移到Chrome扩展。它是一个Angular应用程序。目前,它使用浏览器操作和后台脚本来允许用户调用应用程序注入到页面中。
一旦注入到页面中,扩展应该允许用户再次单击浏览器操作来切换界面的可见性。目前,多次点击浏览器操作会看到后台脚本试图将所有JavaScript文件重新注入页面,抛出如下错误:
警告:尝试加载angular不止一次
我如何在后台脚本中保持一些状态,允许注入接口的切换,而不需要它每次执行扩展的初始化?
Manifest
在我们陷入困境之前,我们需要配置Chrome扩展,使其具有…
- 以权限
activeTab
访问活动选项卡, - 扩展将注入的
web_accessible_resources
(脚本和样式表)列表, - 访问
webNavigation
事件,以便我们知道用户何时刷新或在选项卡内导航, - 和
background.scripts
属性下定义的背景脚本。
让我们看看实际的manifest.json
文件*:
// manifest.json
"background": {
"scripts": ["background.js"]
},
"web_accessible_resources": [
"angular.min.js",
"jquery.min.js",
"main.js",
"style.css"
],
"permissions": [
"activeTab",
"webNavigation",
"http://*/*"
]
*部分清单。json显示
__
选项卡的生命周期状态
这是可能的维护状态(例如,浏览器的操作被点击)为一个标签的生命类似于你如何在其他情况下维护状态,通过维护id
主题的哈希和他们的会话数据。在本例中,主题是一个选项卡。我们可以从浏览器操作的click处理程序中访问选项卡的id
。例如:
// background.js
var clicked = {};
chrome.browserAction.onClicked.addListener(function (tab) {
clicked[tab.id] = (clicked[tab.id] || 0) + 1;
});
选项卡的状态将在导航到其他网页时持续存在,所以我们还需要侦听一个事件,告诉我们导航已经发生,这意味着扩展不再存在于页面中,并重置选项卡的状态:
// background.js continued
// Reset state of our tab data when the page is refreshed
chrome.webNavigation.onDOMContentLoaded.addListener(function (details) {
clicked[details.tabId] = 0;
});
__
条件脚本注入(background.js
)
使用上面的示例,我们可以通过存储一个布尔值来指示扩展是否已经在活动选项卡上初始化,从而执行有条件的脚本注入到页面中。在初始化时,我们想要注入所需的所有脚本,并且在后续的操作调用中只注入我们自己的客户端脚本——假设我们有一个文件main.js
,它构成了扩展自己的有效负载(它不包含只应该注入一次的供应商脚本):
// background.js
var initialised = {};
chrome.webNavigation.onDOMContentLoaded.addListener(function (details) {
initialised[details.tabId] = false;
});
chrome.browserAction.onClicked.addListener(function (tab) {
// When extension already exists in page, load
// a script that will toggle the interface
if (initialised[tab.id]) {
chrome.tabs.executeScript(tab.id, {file: 'main.js'});
return;
}
// Mark this tab as 'initialised'
initialised[tab.id] = true;
var javascripts = [
"jquery.min.js",
"angular.min.js",
"main.js"
];
var stylesheets = [
"style.css"
];
var i;
for (i = 0; i < javascripts.length; i++) {
chrome.tabs.executeScript(tab.id, {file: javascripts[i]});
}
for (i = 0; i < stylesheets.length; i++) {
chrome.tabs.insertCSS(tab.id, {file: stylesheets[i]});
}
});
__
通过注入脚本(main.js
)切换或初始化扩展
注入完成后,我们将处于两个位置之一:
- 扩展需要完整的初始化,因为它是用户第一次在活动选项卡上调用它。(在这种情况下,所有供应商文件和客户端脚本将被注入。)
- 扩展应该在视图内或视图外切换。(在这种情况下,只有客户端脚本会被注入。)
初始化扩展应该通过声明模块和插入所有模板等来完成。(如果扩展完全是自定义的,则按照您认为合适的方式执行初始化。)
因此,我们的main.js
文件应该执行以下操作:
- 寻找一个全局标志(例如
_my_chrome_extension
),表示扩展已经存在于页面中。 - 如果标志存在:
- 获取Angular应用的作用域,并检索属性
isVisible
(或类似的)。 - 将标志设置为当前值(
isVisible = !isVisible
)的相反值。
- 获取Angular应用的作用域,并检索属性
- 如果标志不存在:
- 引导Angular应用程序。
- 在Angular应用中(例如在
run
块或类似的地方)设置属性isVisible
为true,这样界面就会自动出现。
和一个代码示例…
// main.js
(function (angular, $) {
var scope;
// Check if application exists in page already
if (typeof window['_my_chrome_extension'] !== 'undefined') {
var elem = document.querySelector('._extension_container');
scope = angular.element(elem).scope();
}
if (scope) {
// TOGGLE VISIBILITY
scope.isVisible = !scope.isVisible;
scope.$applyAsync();
} else {
window['_my_chrome_extension'] = true;
// PERFORM INITIALISATION
// ANGULAR APP GOES HERE
}
})(angular, jQuery);
作为一个快速的题外话,在你的模板中,你需要像下面这样的东西,根据isVisible
的值显示/隐藏接口:
// template.html
<div id="_my_chrome_extension" ng-show="isVisible"></div>
- D3在一个调用中绘制不同的SVG形状,没有可见性
- jQuery css可见性在load方法中不起作用
- 页面可见性API实际上支持操作系统屏幕锁定吗
- 有没有一种方法可以从隐藏的可见性(CSS,JS)中获得淡入效果
- JavaScript可见性不起作用('隐藏'起作用,'可见'不起作用)
- 从内部回调的可见性
- Openlayers 3为了可见性而绑定到Vector层的复选框没有任何作用
- 在另一个下拉列表中的选择上切换下拉列表中选项的可见性
- 如何禁用mouseout可见性=“;隐藏的“;对小于768px的介质的影响
- 在网格视图的自动刷新过程中,设置内部网格视图文本框的可见性
- 将元素的可见性绑定到另一个元素
- 使用 Javascript 将 HTML 页面中的默认可见性从可见更改为隐藏
- 使用 jQuery 检查文本可见性 .包含代码的行为不符合预期
- 在 jQuery 手风琴样式菜单中切换子项可见性
- CSS 中定义的可见性值未显示在 Javascript 中
- jquery切换可见性
- 如何使用 asp.net 中的另一个下拉列表更改下拉列表选定的索引和可见性
- 使用javascript的图像可见性
- 切换页面内Angular Chrome扩展的可见性
- 数据表列可见性与响应扩展