0

javascript を介して iFrame 内のコンテンツに応じて、Web ページ上の iFrame の高さを動的に調整しようとしています。私の問題は、<script>タグ内のページにスクリプトを直接配置すると、正常に機能することです。コードを別のjsファイルに詰め込んでリンクすると、機能しません!

<iframe id='StatusModule' onload='FrameManager.registerFrame(this)' src='http://randomdomain.dk/StatusModule.aspx'></iframe>

<script type='text/javascript' src='http://randomdomain.dk/FrameManager.js'></script>

それは私にエラーを与えます: Uncaught ReferenceError: FrameManager is not defined

これは本当に真実でしょうか?ページのライフサイクルと関係がありますか?

Ps。JavaScriptコードは機能しないため、無関係だと思います。

更新:これは、セキュア http (https) とさまざまなブラウザーに何らかの奇妙な方法で関係している可能性があると思います。スクリプトが実際にFirefoxで機能することに気付きました。それとも、スクリプトなのか、コンテンツに応じて iframe のサイズを自動的に変更する Firefox の機能なのかはわかりません。ただし、エラーは発生しません。次に、スクリプトの URL 参照に https を追加すると、スクリプトは IE と chrome で機能しますが、Firefox では機能しません。関数参照エラー! なんてこった。これは奇妙になりました!

更新 #2: iframe のサイズを変更する FF 関数ではありません。機能する実際のスクリプトです(httpsなし)。

更新 #3: JavaScript。スクリプトタグに直接入れるとうまくいきます。

var FrameManager = {
        currentFrameId: '',
        currentFrameHeight: 0,
        lastFrameId: '',
        lastFrameHeight: 0,
        resizeTimerId: null,
        init: function () {
            if (FrameManager.resizeTimerId == null) {
                FrameManager.resizeTimerId = window.setInterval(FrameManager.resizeFrames, 0);
            }
        },
        resizeFrames: function () {
            FrameManager.retrieveFrameIdAndHeight();
            if ((FrameManager.currentFrameId != FrameManager.lastFrameId) || (FrameManager.currentFrameHeight != FrameManager.lastFrameHeight)) {
                var iframe = document.getElementById(FrameManager.currentFrameId.toString());
                if (iframe == null) return;
                iframe.style.height = FrameManager.currentFrameHeight.toString() + "px";
                FrameManager.lastFrameId = FrameManager.currentFrameId;
                FrameManager.lastFrameHeight = FrameManager.currentFrameHeight;
                window.location.hash = '';
            }
        },
        retrieveFrameIdAndHeight: function () {
            if (window.location.hash.length == 0) return;
            var hashValue = window.location.hash.substring(1);
            if ((hashValue == null) || (hashValue.length == 0)) return;
            var pairs = hashValue.split('&');
            if ((pairs != null) && (pairs.length > 0)) {
                for (var i = 0; i < pairs.length; i++) {
                    var pair = pairs[i].split('=');
                    if ((pair != null) && (pair.length > 0)) {
                       if (pair[0] == 'frameId') {
                            if ((pair[1] != null) && (pair[1].length > 0)) {
                               FrameManager.currentFrameId = pair[1];
                            }
                        } else if (pair[0] == 'height') {
                            var height = parseInt(pair[1]);
                            if (!isNaN(height)) {
                                FrameManager.currentFrameHeight = height;
                                //FrameManager.currentFrameHeight += 5;
                            }
                        }
                    }
                }
            }
        },
        registerFrame: function (frame) {
            var currentLocation = location.href;
            var hashIndex = currentLocation.indexOf('#');
            if (hashIndex > -1) {
                currentLocation = currentLocation.substring(0, hashIndex);
            }
            frame.contentWindow.location = frame.src + '&frameId=' + frame.id + '#' + currentLocation;
        }
    };
    window.setTimeout(FrameManager.init, 0);

更新 #4: ShadowWizard と TheZuck が提案したとおりにしました。

   <script type="text/javascript">
        var iframe = document.createElement("iframe");
        iframe.src = "http://www.randomdomain.dk/StatusWebModule.aspx";
        iframe.width = '100%';
        iframe.id = 'StatusModule';
        iframe.scrolling = 'no';
        if (iframe.attachEvent) {
            iframe.attachEvent("onload", function () {
                FrameManager.registerFrame(iframe);
            });
        } else {
                iframe.onload = function () {
                    FrameManager.registerFrame(iframe);
                };
            }
  document.getElementById('framecontainer').appendChild(iframe);                                     
        </script>

URL として HTTP を使用すると、IE および FF で動作します - クロムではありません。HTTPS に設定すると、Chrome と IE で動作します - FF ではありません。同じエラー「ReferenceError: FrameManager が定義されていません」。ここで一体何が起こっているのですか?

4

2 に答える 2

1

いくつかのこと:

  1. 同時にロードされるはずの2つの独立したリソースがある場合、競合状態に賭けます。これは、両方の読み込みが完了したときにログ (またはドキュメント、どちらでもよい) に書き込むことで簡単に確認できます (つまり、iframe に小さなスクリプトを追加してコンテンツに時間を動的に追加するか、Chrome を使用している場合はログに書き込みます)。 、外部スクリプトファイルでもそれを行い、これが失敗したときに特定の順序で時間を投稿するかどうかを確認します)。あなたの場合、スクリプトが iframe の前に表示され、それを非同期としてマークしない場合、iframe がフェッチされる前にロードする必要があるため、競合状態のために iframe が見つからないのは奇妙に思えます。その場合は(3)に賭けます。
  2. そのような問題があると仮定すると (そして、現在存在しない場合は、現実の世界に出たときにそうなるでしょう)、これを行うためのより良い方法は、他方が最初にロードされた場合に両方が適切に動作することを確認することです。あなたの場合、スクリプトとは無関係にローカル変数に追加するようにiframeに指示し、ロード時にiframeが登録されているかどうかを確認するようにスクリプトに指示し、その後、iframeが見つかるまで繰り返し間隔で確認します。
  3. スクリプトが読み込まれるページが iframe と同じドメインにない場合 (スクリプトがどこから来たかは問題ではなく、ページのドメインが何であるかだけが重要であることに注意してください)、(または誰かが言及したのと同じプロトコルでさえも)ここ)、コンテンツにアクセスできないため、コンテンツの内容に応じてサイズを変更することはできません。ラッピング ページの一部または内部 iframe の一部と見なされる場合、onload メソッドについてはわかりません。
  4. この質問をチェックしてください。あなたのケースに関連しているようです:
  5. これについては、こちらにも興味深い記事があります。
于 2012-12-18T10:33:24.397 に答える
1

あなたのフレームはスクリプトの前に読み込まれると思うので、iframe の読み込みが完了した時点で「FrameManager」はまだ存在しません。

于 2012-12-18T09:31:42.490 に答える