自動クロスドメインIframe高さ設定

仕事でiframeに出会った人の多くは、このiframeの高さを設定するタスクにも出会ったと思います。



これは、たとえば、ユーザーが自分のサイトのウィジェットを自分のサイトに配置できるようにし、ウィジェットのコンテナ(iframe)をこのウィジェットのコンテンツのサイズに一致させる場合に必要になることがあります。



Yandexでこの問題の多くの解決策を見つけることができますが、それらのほとんどに1つの問題があります。iframeと親のコンテンツが異なるドメインにある場合、ウィンドウのサイズを変更する機能をサポートしていません。



1つの優れたクロスドメインソリューションがありますが、それは2007年に記述されたものであり、それ以来多くの変更が加えられています。 したがって、上記のソリューションに基づいて、この問題の解決策を自分で開発する必要がありました。







実際、主な変更点はwindow.postMessageツールです。これにより、ブラウザーウィンドウでメッセージを交換できます。 これにより、上記のソリューションの類似物を作成できます。これには次の利点があります。





私たちのコードは外部要因に依存するべきではなく、その使用のために、フレームのコンテンツの側に2つのjsファイル(postMessageと泥棒-私たちのもの)とクライアント側-2つのjsファイルを接続して追加するのに十分でなければなりませんiframeには2つの属性があります-idとname(同一である必要があります)、またifloadにはi​​frame登録がハングアップします。



postmessageを使用するには、次のライブラリを使用します。

postmessage.freebaseapps.com

このライブラリは、window.postMessageの非常に便利なラッパーです。これにより、とりわけ、window.postMessageをサポートしていないブラウザーでハッシュを介したデータ転送を使用できます。



スクリプトのロジックは非常に単純です-クライアントページでiframeを「登録」します-このiframeの識別子を子ページ(iframeにあります)に送信し、子ページからのメッセージをサブスクライブします。 メッセージの受信時に-サイズ変更。



子ページ(iframe内)の側で、到着時に登録メッセージをサブスクライブします-識別子を覚えて、タイマーをオンにします。タイマーは、フレームコンテンツのサイズが変更されると、iframeのサイズを変更する必要があるという情報を親ページに送信します。



それだけです。 スクリプトコード自体:



FrameManager.js(「クライアント」スクリプト)

var FrameManager = { registerFrame : function(frame) { pm({ target: window.frames[frame.id], type: "register", data: {id:frame.id}, url: frame.contentWindow.location }); pm.bind(frame.id, function(data) { var iframe = document.getElementById(data.id); if (iframe == null) return; iframe.style.height = (data.height+12).toString() + "px"; }); } };
      
      







Frame.js(フレームのコンテンツのスクリプト)

 var FrameHeightManager = { FrameId: '', getCurrentHeight : function() { myHeight = 0; if( typeof( window.innerWidth ) == 'number' ) { myHeight = window.innerHeight; } else if( document.documentElement && document.documentElement.clientHeight ) { myHeight = document.documentElement.clientHeight; } else if( document.body && document.body.clientHeight ) { myHeight = document.body.clientHeight; } return myHeight; }, publishHeight : function() { if (this.FrameId == '') return; //   jQuery -        if(typeof jQuery === "undefined") { var actualHeight = (document.body.scrollHeight > document.body.offsetHeight)?document.body.scrollHeight:document.body.offsetHeight; var currentHeight = this.getCurrentHeight(); } else { var actualHeight = $("body").height(); var currentHeight = $(window).height(); } if(Math.abs(actualHeight - currentHeight) > 20) { pm({ target: window.parent, type: this.FrameId, data: {height:actualHeight, id:this.FrameId} }); } } }; pm.bind("register", function(data) { FrameHeightManager.FrameId = data.id; //     this window.setInterval(function() {FrameHeightManager.publishHeight.call(FrameHeightManager)}, 300); });
      
      







そして、2つのテストhtmlページを書きます:



test.html(親)

 <!DOCTYPE html> <html> <body> <script src="postmessage.js"></script> <script src="FrameManager.js"></script> <iframe height="10" id="frame1" name="frame1" src="test2.html" onload="FrameManager.registerFrame(this)" scrolling="no" frameborder="0" marginheight="0" marginwidth="0" ></iframe> </body> </html>
      
      







test2.html(子)

 <!DOCTYPE html> <html> <body> <!--<script src="http://yandex.st/jquery/1.7.1/jquery.min.js"></script>--> <script src="postmessage.js"></script> <script src="Frame.js"></script> <div style="border:1px solid red;margin:0; height:200px;"> test </div> </body> </html>
      
      







子ページでは、jquery接続を使用してコードのコメントを解除することもできます。これにより、高さの決定がより正確になります。 ページとウィンドウのサイズを決定するための通常のクロスブラウザ機能に感謝します。最初に見つけたものを使用しました-それらは動作しますが、Webkitの10ピクセルではエラーが発生します。



クライアント側(つまり子ページ)にjqueryがあるため、これは私にとって重要ではありませんが、誰かが持っていない可能性があります-コードは引き続き機能します。



All Articles