Rik*_*tor 9 javascript firefox firefox-addon firefox-addon-sdk
发现清洁溶液
我找到了一个非常干净的解决方案,它真的让整个问题变得毫无意义,我确信当我提出这个问题时它就存在了......我也很无知也在寻找它.
attachTo: 'top'在PageMod构造函数中使用只将脚本附加到顶级文档而不是任何文档iframes.
因此,如果您发现PageMod附加内容多次附加,则可能是因为它iframes与顶级选项卡文档一起附加.添加attachTo: 'top'为传递给PageMod构造函数的对象的属性,您不必担心iframes.
对于下面的问题,解决方案将是
var _workers = [];
var pageMod = require("sdk/page-mod").PageMod({
include: /https?:\/\/www\.websitename\.net.*/,
contentScript: "self.port.on('hello', function() { " +
"console.log('['+document.location.href+']: " +
"My worker said hello to me!');",
contentScriptWhen: "end",
attachTo: 'top', //<-- add this property to only attach to top level document
onAttach: function(worker) {
_workers.push(worker);
worker.on("detach", function() {
var ind = _workers.indexOf(this);
if(ind !== -1) {
_workers.splice(ind, 1);
}
});
worker.port.emit("hello");
}
});
Run Code Online (Sandbox Code Playgroud)
当然,如果没有@ Noitidart的帮助,我永远不会指出原因iframes.
老问题
我正在尝试为Firefox编写一个附加组件,用于修改特定网站的页面.我认为这PageMod是完美的选择,但我遇到了一些问题.工人似乎多次附加到同一个URL(4到2),我也不知道为什么会发生这种情况.
我在附加组件的main.js中尝试了以下代码:
var _workers = [];
var pageMod = require("sdk/page-mod").PageMod({
include: /https?:\/\/www\.websitename\.net.*/,
contentScript: "self.port.on('hello', function() { " +
"console.log('['+document.location.href+']: " +
"My worker said hello to me!');",
contentScriptWhen: "end",
onAttach: function(worker) {
_workers.push(worker);
worker.on("detach", function() {
var ind = _workers.indexOf(this);
if(ind !== -1) {
_workers.splice(ind, 1);
}
});
worker.port.emit("hello");
}
});
Run Code Online (Sandbox Code Playgroud)
在运行此代码并https://www.websitename.net在单个单独的选项卡中打开时,控制台有2到4个实例
[https://www.websitename.net/]: My worker said hello to me!
Run Code Online (Sandbox Code Playgroud)
这意味着同一页面附加了多个工作人员.我不知道为什么会这样,我当然不希望它,因为我打算以后使用_workers数组与附加的脚本进行通信.
编辑:
感谢@Noitidart,我现在已经确认了多个工作者,只有一个是实际页面,其他是iframe,这就是为什么每个工作者的内容脚本可用的DOM内容不同.
但问题仍然存在.如何确保工作人员(以及内容脚本)没有附加到iframe?
我可以确保没有附加到a的工作者是iframe被推送到的工作者_workers,但是一旦我确定它是正确的,有没有办法将内容脚本附加到工作者?我不希望多次附加相当大的内容脚本.
编辑2:
再次,感谢@Noitidart,我认为我有一些解决方案:如果检测到工作者被附加到一个,则销毁iframe.
更好的解决方案是仅将主内容脚本附加到正确的工作者,但目前我无法找到将内容脚本附加到正确的工作者的方法(worker.contentScriptFile = data.url("file.js")似乎不起作用).
所以,目前的黑客:
verify.js:
if(window.top !== window) {
self.port.emit('iframe');
}
else {
self.port.emit('hi');
}
Run Code Online (Sandbox Code Playgroud)
main.js:
var _workers = [];
var pageMod = require("sdk/page-mod").PageMod({
include: /https?:\/\/www\.websitename\.net.*/,
contentScriptFile: [data.url("verify.js"), data.url("my_main_script.js")],
contentScriptWhen: "end",
onAttach: function(worker) {
worker.on("detach", function() {
var ind = _workers.indexOf(this);
if(ind !== -1) {
_workers.splice(ind, 1);
}
});
worker.port.on("hi", function() {
//Not iframe, keep this one.
//If there is a way, attach 'my_main_script.js'
//to this worker now, and not before.
_workers.push(worker);
//Emit 'ack' to tell my_main_script.js
//that we're good to go.
worker.port.emit('ack');
});
worker.port.on("iframe", function() {
//iframe, get rid of it.
worker.destroy();
});
}
});
Run Code Online (Sandbox Code Playgroud)
我应该注意,contentScriptFile脚本出现的顺序并不重要,两个脚本都为每个附件加载.所以毫无疑问,在加载my_main_script.js之前,verify.js会破坏worker .
而且,这个解决方案还没有完成.如果我在这一点上没有足够强调,我真的希望有一种方法可以将my_main_script.js附加到正确的工作者,而不是为所有工作者加载它.如果有这样的方式,请评论/回答.
在 contentScript 或网站中运行的任何内容中(我对 sdk 不太了解),检查if (window.frameElement == true)它是否比它的框架更真实,然后你想取消附加。
编辑:也许 window.frameElement 无法在框架内工作。如果它不起作用,if (window.top != window)那么它是一个框架
| 归档时间: |
|
| 查看次数: |
1156 次 |
| 最近记录: |