我正在开发一个firefox插件,我需要的一个功能是在用户导航的页面中注入一个弹出元素。
我尝试在身体中注射DIV,但是我的DIV继承了页面CSS并且每个页面的弹出显示都不同,所以我决定将它添加到iframe中。
这是插件代码: main.js
exports.main = function() {};
var page_mod = require("page-mod");
var data = require("self").data;
var self = require("self");
function initPageMod()
{
myPageMod = page_mod.PageMod({
include: ['*'],
contentScriptWhen: "start",
contentScriptFile: [data.url("jquery.js"), data.url("modPage.js")],
onAttach: function(worker) {
worker.port.emit("inject", data.load("iframecontent.html"));
}
});
}
initPageMod();
我在这里做的是在每个页面上安装一个page-mod,注入jquery和我的modPage.js并在连接时调用“inject”端口。 iframecontent.html:
<html>
<head>
<title>title</title>
<script type="text/javascript">
window.showPopup = function() {
}
</script>
</head>
<body>
body
</body>
</html>
这是一个非常简单的HTML文件,带有一个脚本标记,用于定义我想从父文档调用的showPopup函数。
modPage.js:
self.port.on("inject", function(iframeContent) {
$(function(){
if(window.frameElement == null) {
$('body').append(
'<div id="myExternalDiv" style="position:fixed;width:2560;height:auto;float:left;left:0px;top:0px;z-index:2147483647;overflow-x:hidden;overflow-y:hidden;background: transparent;margin: 0px;padding: 0px;">' +
'<iframe id="myMagicIframe" width="100%" height="100%" frameborder="0" style="width:100%; overflow-y: hidden;background-color:transparent;" scrolling="no" marginheight="0" frameborder="0" allowtransparency="true" onload="alert(1)"></iframe>' +
'</div>'
);
try {
var oIframe = document.getElementById("myMagicIframe");
var iframeDoc = (oIframe.contentWindow.document || oIframe.contentDocument);
iframeDoc.open();
iframeDoc.write(iframeContent);
iframeDoc.close();
} catch (err) {
alert(err);
}
setTimeout(function(){func()}, 5000);
}
});
});
function func() {
if (document.getElementById("myMagicIframe") != null) {
try {
document.getElementById("myMagicIframe").contentWindow.showPopup();
}catch(err) {
alert(err);
setTimeout(function(){func()}, 1000);
}
}
}
“inject”在div中创建一个iframe,在其中写入iframecontent并在5秒后调用func函数。 发生的事情是我收到以下异常: “showPopup不是一个函数”。 document.getElementById(“myMagicIframe”)。contentWindow.showPopup未定义。
如果我在HTML中添加上面的代码并在firefox中运行它可以工作并调用showPopup函数,但在插件中它不起作用。
我正在使用插件构建器: https://builder.addons.mozilla.org/package/159673/latest/
谢谢
答案 0 :(得分:2)
首先感谢canuckistani让我知道代理概念。当您添加page-mod时,您的脚本将在沙箱上运行,您使用的变量是代理。
更改以下文件:
document.getElementById("myMagicIframe").contentWindow.showPopup();
到
document.getElementById("myMagicIframe").contentWindow.wrappedJSObject.showPopup();
解决了这个问题。
我的iframe被添加到页面中,因此showPopup函数被添加到真实窗口对象中。 currentWindow对象是一个代理,没有添加的功能。使用wrappedJSObject对象,我能够获得真正的窗口对象并调用函数。
答案 1 :(得分:1)
这种情况正在发生,因为任何从不同服务器加载iframe的页面(或者在这种情况下,通过资源uri)都无法通过框架边界访问另一个文档。
我最好的建议是将一个附加到iframe的内容脚本发送回main.js的消息,然后可以将消息路由到附加到父文档的内容脚本。它是间接的,但它会起作用。
欲了解更多信息:
类似的例子,但使用面板:
https://builder.addons.mozilla.org/package/159682/latest/
使用内容脚本的文档: