javascript - 在多个用户脚本之间共享库
问题描述
我有一个由多个用户脚本使用的库脚本。这个库做了一些繁重的工作(即 CPU 密集型操作),所以我希望只运行该库的 1 个实例。
这是一个最小的例子:
lib.js
let callbacks = [];
document.addEventListener('click', function(event){
// pretend that something expensive happens in here
for (callback of callbacks)
callback();
});
script1.user.js
// @match foo.bar
// @require lib.js
callbacks.push(function(){
console.log('Script 1: '+callbacks.length+' callback(s) registered');
});
script2.user.js
// @match foo.bar
// @require lib.js
callbacks.push(function(){
console.log('Script 2: '+callbacks.length+' callback(s) registered');
});
使用此设置,单击鼠标后的输出将是:
Script 1: 1 callback(s) registered
Script 2: 1 callback(s) registered
因为每个用户脚本都有自己的库实例。我该怎么做才能让它们使用相同的库实例,所以我得到这样的输出:
Script 1: 2 callback(s) registered
Script 2: 2 callback(s) registered
笔记:
- 两个用户脚本在同一页面上运行
- 用户脚本可能有也可能没有
@grant none
解决方案
最简单的方法是让库脚本在窗口尚不存在时将其自身分配给窗口,标准单例样式。
lib.js
const win = typeof unsafeWindow === 'undefined' ? window : unsafeWindow;
if (!win.myLib) {
win.myLib = {
callbacks: []
// assign other properties/methods as needed
};
document.addEventListener('click', function(){
for (const callback of win.myLib.callbacks)
callback();
});
}
script1.user.js
// @require lib.js
const { myLib } = window;
myLibrary.callbacks.push(function(){
console.log('Script 1: ' + myLib.callbacks.length + ' callback(s) registered');
});
script2.user.js
// @require lib.js
const { myLib } = window;
myLibrary.callbacks.push(function(){
console.log('Script 2: ' + myLib.callbacks.length + ' callback(s) registered');
});
根据用户脚本管理器,您可能不得不unsafeWindow
在某些情况下使用。
推荐阅读
- javascript - 如何在mongo中替换数组中的值?
- excel - 根据重复和日期设置条件
- swift - 如何使用 Vapor Swift 获取 URL 的 HTML?
- css - 容器的宽度在 Chrome for windows 上计算错误
- r - 在ggplot2中对Y轴值进行升序排序
- javascript - 显示 JSON 数据 HTML - 未定义
- spring-boot - 我可以使用我的电子邮件地址作为 RabbitMQ 用户名吗?
- ios - 添加手势识别器后未修改 UICollectionViewCell 背景颜色
- html - 如何使用 xpath 查找具有两个特定后代的元素?
- npm - NPM 安装错误无法找到:“CL.exe”。该系统找不到指定的文件