0

最初にjQueryライブラリを作成してiframeから挿入しようとしていますが、jQueryがロードされたことを示すアラートが表示されます。

jQuery ライブラリは期待どおり head に挿入され、iframejQuery ロードに関するアラートは body に挿入されています。

問題は、アラートが表示されず、代わりにjQuery is not defined.

誰でも何か提案できますか?

ここにコードがあります

<!doctype html>
<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
        <title>iFrame Test</title>
    </head>
    <body>
        <script>
            var insertScript = function(src){
                var script = document.createElement('script');
                script.type = 'text/javascript';
                script.async = false;
                script.src = src;
                $('iframe').contents().find('head')[0].appendChild(script);
            }

            var insertScriptContent = function(code){
                var script = document.createElement('script');
                script.type = 'text/javascript';
                script.async = false;
                script.innerHTML  = code;
                $('iframe').contents().find('body')[0].appendChild(script);
            }

            $(function(){
                $('iframe').load(function(){
                    var contents = $('iframe').contents();
                    insertScript('https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js');
                    insertScriptContent('jQuery(function(){ alert("loaded"); });');
                });
            });
        </script>

        <div class="output">
            <iframe></iframe>
        </div>
    </body>
</html>
4

1 に答える 1

2

(にもかかわらず) jQuery を非同期的script.async=falseに読み込み、その直後にアラート スクリプトを読み込みます。そのスクリプトの実行時に jQuery はまだロードされていないため、未定義のjQuery参照が取得されます。

簡単な修正として、が定義されるsetInterval()まで待機するを追加しました。jQuery他にも次の変更を加えました。

  • script.async = false;何の役にも立たないので、両方の場所を削除しました。
  • $('iframe').load()ラッパーを削除しました。コードをテストしたところ、そのラッパーのコールバック関数はまったく呼び出されませんでした。その時点で iframe には何もロードされていないため、これは驚くべきことではありません。
  • document.createElement()代わりにiframe ドキュメント (iframedoc私のバージョンでは呼び出されます)を使用するために使用する 2 つの場所を変更しました。を使用しても問題なく動作しdocumentますが、読み込まれるドキュメントの下にこれらのスクリプトを作成する方が少し快適です。
  • の 2 つのインスタンスを...find(something)[0].appendChild();より単純なに変更しました...find(something).append();

作業コードは次のとおりです。

<!doctype html>
<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript">
</script>

    <title>iFrame Test</title>
</head>

<body>
    <script type="text/javascript">

        $(function() {
            var $contents = $('iframe').contents();
            var iframedoc = $contents[0];

            var insertScript = function(src) {
                var script = iframedoc.createElement('script');
                script.type = 'text/javascript';
                script.src = src;
                $('iframe').contents().find('head').append(script);
            }

            var insertScriptContent = function(code) {
                var script = iframedoc.createElement('script');
                script.type = 'text/javascript';
                script.innerHTML = code;
                $('iframe').contents().find('body').append(script);
            }

            insertScript('https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js');

            insertScriptContent(
                'var timer = setInterval( function() {' +
                    'if( typeof jQuery == "undefined" ) return;' +
                    'clearInterval( timer );' +
                    'jQuery(function(){ alert("loaded"); });' +
                '}, 50 )'
            );

        });
    </script>

    <div class="output">
        <iframe></iframe>
    </div>
</body>
</html>

最初のパスとしてはこれでよかったのですが、もっと簡単な方法があります。2 つのスクリプト関数を jQuery コードに置き換えてみたので、別の作業バージョンを次に示します。

<!doctype html>
<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript">
</script>

    <title>iFrame Test</title>
</head>

<body>
    <script type="text/javascript">

        $(function() {
            var $contents = $('iframe').contents();

            $contents.find('head').append(
                '<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"><\/script>'
            );

            $contents.find('body').append(
                '<script>' +
                    'jQuery(function(){ alert("loaded"); });' +
                '<\/script>'
            );

        });
    </script>

    <div class="output">
        <iframe></iframe>
    </div>
</body>
</html>

奇妙なことに、これはタイマーがなくても問題なくsetInterval()動作するので、そのコードを取り出しました。なぜこれが機能するのか正確にはわかりませんが、これは快適な感覚ではありませんが、私がテストしたブラウザーでは一貫しているようです.

そして最後に、これは機能しない実験です。過去にdocument.write()、iframe をターゲットにして効果を上げてきました。だから私はそれを試してみようと思った:

<!doctype html>
<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript">
</script>

    <title>iFrame Test</title>
</head>

<body>
    <script type="text/javascript">

        $(function() {
            var $contents = $('iframe').contents();
            var iframedoc = $contents[0];

            iframedoc.write(
                '<!doctype html>',
                '<html>',
                '<head>',
                    '<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.js"><\/script>',
                '</head>',
                '<body>',
                    '<script>',
                        'debugger;',
                        'jQuery( function(){ alert("loaded"); } );',
                    '<\/script>',
                '</body>',
                '</html>'
            );
        });
    </script>

    <div class="output">
        <iframe></iframe>
    </div>
</body>
</html>

このバージョンでは、jQuery とインライン スクリプトが iframe に読み込まjQuery()れ、インライン スクリプトで呼び出しが実行されます。ただし、 を含むコールバック関数を呼び出すことはありませんalert()。これは実際に私が取り組んでいるものに関連しているので、おそらく明日もう一度見てみますが、それまでの間、興味がある場合に備えて実験的なコードを残しました. 簡単にデバッグできるように、iframe 内で圧縮されていない jQuery を使用するように変更しdebugger;、そこにステートメントを残しました。

于 2013-04-17T06:18:09.827 に答える