2

Firefox アドオンを開発していますが、必要な機能の 1 つは、ユーザーがナビゲートしているページ内にポップアップ要素を挿入することです。

本文に 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>

これは、親ドキュメントから呼び出したい showPopup 関数を定義するスクリプト タグを含む非常に単純な HTML ファイルです。

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/

ありがとうございました

4

2 に答える 2

2

最初に、プロキシの概念を知らせてくれた canuckistani に感謝します。page-mod を追加すると、スクリプトはサンドボックスで実行され、使用する変数はプロキシになります。

次のファイルを変更します。

document.getElementById("myMagicIframe").contentWindow.showPopup();

document.getElementById("myMagicIframe").contentWindow.wrappedJSObject.showPopup();

問題を解決しました。

私のiframeがページに追加されていたため、showPopup関数が実際のウィンドウオブジェクトに追加されていました。currentWindow オブジェクトはプロキシであり、追加された機能がありませんでした。ラップされたJSObject オブジェクトを使用して、実際のウィンドウ オブジェクトを取得し、関数を呼び出すことができました。

于 2012-11-05T21:30:36.067 に答える
1

これは、iframeが異なるサーバーから(またはこの場合はリソースURIを介して)ロードされる他のページと同様に、フレームの境界を越えて他のドキュメントにアクセスできないために発生します。

私の最善の提案は、iframeに添付されたコンテンツスクリプトにメッセージをmain.jsに返送させ、親ドキュメントに添付されたコンテンツスクリプトにメッセージをルーティングできるようにすることです。間接的ですが、機能します。

詳細情報:

同様の例ですが、パネルを使用しています。

https://builder.addons.mozilla.org/package/159682/latest/

コンテンツスクリプトの使用に関するドキュメント:

https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/guides/content-scripts/index.html

于 2012-11-01T21:14:41.497 に答える