Iframe 適応高さコードに関する 3 つの議論

Iframe 適応高さコードに関する 3 つの議論
B/S システム インターフェースを構築する場合、メイン ページ index.html 内に他のページがネストされている状況に遭遇することがよくあります。一部のライブラリでは既にコントロールが提供されていますが (jQuery easy UI など)、iframe の使用が避けられない場合もあります。この記事では、比較的実用的な回答が得られるはずです。記事にもあるように、インターネット上のほとんどのものはゴミか信頼できないものです。原文は上田幸兵衛氏が編集!
なぜ3回も講演するのですか?
なぜ3回も講演するのですか?理由の 1 つは、このトピックはよく話題になっているためであり、もう 1 つの理由は、Master Tai が数年前に iframe の適応型の高さについて論じたこの記事を書いたためです。私がこの問題を再度取り上げる理由は、以前のプロジェクトでこの問題のあらゆる側面に遭遇したため、それを要約する必要があるからです。これが役に立つことを願います。間違いがあれば指摘してください。
最も単純なケースは、同じドメイン内のサブページの高さが動的に増加しない場合です。スクリプトを通じてサブページの実際の高さを直接取得し、iframe 要素の高さを変更できます。ただし、注意すべき点が 2 つあります。
ページ上に絶対位置の要素やクリアされていないフローティング要素がある場合、状況は少し複雑になります。Webkit カーネルを搭載したブラウザーであっても、ブラウザーによって結果の処理方法が異なります。詳細については、このデモを参照してください。したがって、ブラウザ検出を行うか、Math.max を使用して最大値を計算するか、別の方法を考える必要があります。
iframe に含まれるページは非常に大きく、読み込みに長い時間がかかる場合があります。そのため、高さを直接計算する場合、ページがまだダウンロードされていない可能性が高く、高さの計算に問題が生じます。したがって、iframe の onload イベントで高さを計算する方が適切です。ここで、IE で onload イベントをバインドするには、Microsoft イベント モデル obj.attachEvent を使用する必要があることにも注意してください。他のブラウザの場合は、obj.onload = function(){} を直接使用することもできます。

コードをコピー
コードは次のとおりです。

(関数(){
var フレーム = document.getElementById("frame_content_parent"),
setIframeHeight = 関数(){
var frameContent = frame.contentWindow.document,
frameHeight = Math.max(frameContent.body.scrollHeight、frameContent.documentElement.scrollHeight);
フレームの高さ = フレームの高さ;
};
フレームにイベントリスナーを追加します。
frame.addEventListener("load",setIframeHeight,false);
}それ以外{
フレームをアタッチするイベントを"onload"に設定し、IframeHeightを設定します。
}
})();

同じドメインとサブページの高さが動的に増加します。原理は最初のケースと同じです。サブページの高さを検出し続けるために追加のタイマーが追加されます。サブページの高さが iframe の高さと一致しない場合、iframe の高さがリセットされます。 js エラーが発生したときに十分な高さを追加するために、ここで try を追加することもできます。

コードをコピー
コードは次のとおりです。

(関数(){
var _reSetIframe = 関数(){
var フレーム = document.getElementById("frame_content_parent")
試す {
var frameContent = frame.contentWindow.document,
bodyHeight = Math.max(frameContent.body.scrollHeight、frameContent.documentElement.scrollHeight);
bodyHeight != frame.height の場合{
フレームの高さ = bodyHeight;
}
}
キャッチ(例) {
フレームの高さ = 1800;
}
}
フレームにイベントリスナーを追加します。
frame.addEventListener("load",function(){setInterval(_reSetIframe,200);},false);
}それ以外{
フレームにイベントを添付します("onload",function(){setInterval(_reSetIframe,200);});
}
})();

2 番目の例では、スクリプト エラーが考慮されています。しかし、スクリプトがまったく実行されない場合はどうなるでしょうか。iframe の高さが十分ではないため、iframe 内のコンテンツは表示されません。このため、通常は事前に十分な高さを設定します。フロントエンドの制御の利便性を考えると、CSS ファイルに記述する方が適切だと思います。変更が必要な場合は、CSS のみを変更する必要があります。ここではセレクタ{ height:1800px; }を設定しました。スタイルシートに記述されたスタイルは、node.style[property] を使用して直接取得できないことに注意してください。Microsoft モデルの場合は、node.currentStyle[property] を使用する必要があります (話題から外れますが、残念なことに IE モデルは CSS 疑似クラスをサポートしていません)。W3C モデルの場合は、window.getComputedStyle(node,null)[property] を使用する必要があります。便宜上、YUI を使用しました。
ここで別の問題があります。iframe の高さが、それに含まれるページの高さよりも大きく設定されている場合、各ブラウザはそれを異なる方法で処理します。たとえば、Firefox では body 要素の高さを計算する必要があり、html 要素の高さは iframe の高さに等しくなります。ただし、ページに絶対位置が不明瞭なフローティング要素がある場合は、body 要素を通じて取得することはできません。明らかに、最初の方法の方が欠点は少なくなります。詳細については、このデモをご覧ください。
上記のデモから、IE ブラウザを除く他のブラウザは、CSS で設定された #frame_content_parent{ height:1800px; } である iframe の高さを計算していることがわかります。 IE が計算するのは、iframe によって参照されるページの実際の高さです。

コードをコピー
コードは次のとおりです。

#frame_content_parent{ 高さ:1800px; }
(関数(){
var $ = YAHOO.util.Dom、
フレーム = $.get("frame_content_parent");
関数 reSetIframe(){
var frameContent = frame.contentWindow.document,
bodyHeight = Math.max(frameContent.documentElement.scrollHeight、frameContent.body.scrollHeight);
bodyHeight != $.getStyle(frame, "height") の場合{
$.setStyle(フレーム、"高さ"、ボディ高さ + "px");
}
}
if(フレーム){
$.setStyle(フレーム、高さ、自動)。
フレーム間隔を300に設定します。
}
})();

ここでは、クロスドメイン Iframe プロキシ方式とその原理を簡単に説明します。メインページ A.html、サブページ B.html、プロキシページ C.html の 3 つのページがあるとします。 A と B はクロスドメインですが、A と C は同じドメイン内にあります。それらの関係: A には B が含まれ、B には C が含まれます。当然、A と B、B と C はドメインが異なっているため相互に通信できませんが、A と C は同じドメイン内にあるため相互に通信できます。このため、ページ C がページ A にページ B がどのくらい高いかを伝えるようにすることを考えました。 B と C もクロスドメインであり、相互に通信できないため、ページ C で window.parent.document.body.scrollHeight を直接使用することは現実的ではありません。したがって、ページ B に独自の高さを計算させ、何らかの方法でページ C に伝え、ページ C がページ A に伝えることしかできません。ここでの 1 つの方法は、ページ B に Iframe ノードを生成し、その src 属性を設定し、このアドレスにパラメータ (つまり、ページ B によって計算された高さ) を追加します。その後、ページ C は window.location を通じてアドレス バーのアドレスを取得し、高さの値を抽出し、window.top を通じてページ A を見つけて、ページ A の Iframe の高さを設定します。基本的な原則は次のとおりです。コードを見てみましょう。
デモ

コードをコピー
コードは次のとおりです。

//Bページスクリプト
//タスク: 実際の高さを計算し、iframe ノードを生成し、プロキシ ページ C のアドレスの一部として高さを Src 属性に割り当てます。
(関数(){
var agent_iframe = document.createElement("iframe"),
b_height = Math.max(document.documentElement.scrollHeight、document.body.scrollHeight);
agent_iframe.src = "http://demo.zhouqicf.com/js/2010/iframe_height/agent_iframe_once.html#" + b_height;
ドキュメント本体に子要素を追加します(agent_iframe)。
agent_iframe.style.display = "なし";
})();


コードをコピー
コードは次のとおりです。

//Cページスクリプト
//タスク: リクエストアドレスの高さの値を取得し、ページ A の Iframe の高さに割り当てます。
window.top.document.getElementById("frame_content_parent").height = parseInt(window.location.hash.substring(1),10);

クロスドメイン、単語ページの高さが動的に変化する

ここでは、2 番目と 4 番目の方法が組み合わされています。私のアイデアは、ページ B のタイマーを使用して、ページ B の高さを継続的に計算することです。高さが変更されると、iframe タグの src 属性がすぐに変更されます。ページ C にも、src の変化を継続的に監視し、iframe タグの高さを変更するタイマーがあります。 src 属性の後のアンカー値 (「#1234」など) を変更するだけでは、ページは更新されず、再リクエストも行われないことに注意してください。このため、ページ C にタイマーが追加されます。


コードをコピー
コードは次のとおりです。

//Bページスクリプト
(関数(){
var getHeight = 関数(){
Math.max(document.documentElement.scrollHeight、document.body.scrollHeight) を返します。
};
var preHeight = getHeight(),
エージェントiframe;
var createIframe = function(height){
agent_iframe = document.createElement("iframe");
agent_iframe.style.height = "0";
agent_iframe.style.width = "0";
agent_iframe.style.border = "なし";
agent_iframe.src = "http://demo.zhouqicf.com/js/2010/iframe_height/agent_iframe.html#" + 高さ;
ドキュメント本体に子要素を追加します(agent_iframe)。
}
Iframe を作成します (preHeight);
var checkHeight = 関数(){
var 現在の高さ = getHeight();
現在の高さが現在の高さと等しい場合
agent_iframe.src = "http://demo.zhouqicf.com/js/2010/iframe_height/agent_iframe.html#" + 現在の高さ;
preHeight = 現在の高さ;
}
タイムアウトを設定します(checkHeight,500);
}
タイムアウトを設定します(checkHeight,500);
})();


コードをコピー
コードは次のとおりです。

//Cページスクリプト
(関数(){
var preHeight = parseInt(window.location.hash.substring(1),10)、
ifrmae = window.top.document.getElementById("frame_content_parent");
ifrmae.height = プレHeight;
setInterval(関数(){
var newHeight = parseInt(window.location.hash.substring(1),10);
(newHeight !== preHeight)の場合{
ifrmae.height = 新しい高さ;
プレハイト = 新しいハイト;
}
},500);
})();

ここで別の解決策があります。それは、iframe が毎回再リクエストするようにすることです。これにより、ページ C はタイマーを必要としません。ただし、高さが 2 回計算されると、src 属性の値が同じになるため、ブラウザーはページを再リクエストしない可能性が高くなり、ページ C のスクリプトは実行されません。計算された各 src 属性に乱数パラメータを追加することで、この問題を簡単に修正できます。たとえば、http://demo.zhouqicf.com/js/2010/iframe_height/agent_iframe.html?temp=123123423712937#1563


コードをコピー
コードは次のとおりです。

//Bページキースクリプト
agent_iframe.src = "http://demo.zhouqicf.com/js/2010/iframe_height/agent_iframe.html?a=" + Math.random() + "#" + 現在の高さ;
//Cページスクリプト
window.top.document.getElementById("frame_content_parent").height = parseInt(window.location.hash.substring(1),10);

<<:  フローティング要素が親要素の高さを崩す原因と解決策の詳細な説明

>>:  テキストエリア テキストエリアの幅と高さ 幅と高さの自動適応実装コード

推薦する

...

MySQL 5.6 の「暗黙的な変換」によりインデックスが失敗し、データが不正確になる

背景SQL クエリを実行するときに、where 条件の vachar 型フィールドの単一引用符を削除...

ページング効果を実装するミニプログラム

この記事の例では、ページング効果表示を実現するためのミニプログラムの具体的なコードを参考までに共有し...

HTML テーブルタグチュートリアル (33): セルの垂直配置属性 VALIGN

垂直方向では、セルの配置を上、中央、下に設定できます。基本的な構文<TD VLIGN=&quo...

MySQL の日付関数と日付変換およびフォーマット関数

MySQL は、膨大なユーザーベースを持つ無料のリレーショナル データベースです。この記事では、My...

HTMLはマーキーを使用してテキストを左右にスクロールします

コードをコピーコードは次のとおりです。 <本文> //マーキーの助けを借りて<MA...

Alibaba Cloud CentOS 7 に yum を使用して MySQL をインストールする正しい方法 (推奨)

yum クイックインストール mysql yumリポジトリを追加する rpm -Uvh http:...

MySQLクエリトランザクション処理へのノード接続の実装

目次トピックmysqlの追加、削除、変更、クエリを入力しますMySQL トランザクション処理私は M...

手の動きをリアルタイムで監視するための Handtrack.js ライブラリ (推奨)

【はじめに】: Handtrack.jsは、ブラウザ上で直接リアルタイムの手の動きの追跡と検出を実...

Vueはチャットインターフェースを実装する

この記事の例では、チャットインターフェースの表示を実現するためのVueの具体的なコードを参考までに共...

JavaScriptでカレンダー効果を素早く実装

この記事では、カレンダー効果を素早く実現するためのJavaScriptの具体的なコードを例として紹介...

mysql エラー 1045 (28000) - ユーザーへのアクセスが拒否される問題を解決する方法

問題の説明 (以下の説明は Windows 環境に限定されます): D:\develop\ide\m...

EclipseのプロジェクトをTomcatに追加できない問題を解決する方法

1. プロジェクトを右クリックしてプロパティを選択します2. プロジェクトファセットをクリック3. ...