iframeで読み込んだ、動的コンテンツの高さに応じて親フレームの高さも調整したい事ってありますね!
結構すんなり出来る事なんですけど、ただ、クロスサイトになると制約がいっぱいなので単純には行きま。
ググった結果web Messagingってのを使うことにしました。
Web Messagingを使う
web messagingとは、異なるサイト間でメッセージのやり取りが出来る機能です。クライアント間で完結します。
こちらに詳細載ってます。Web Messagingとは
この機能には、チャネルメッセージング
とクロスドキュメントメッセージング
の二つのAPIが用意されています。
今回はクロスドキュメントメッセージング
を使用します。
クロスドキュメントメッセージングは、この異なるオリジンの間での通信を安全に行うことを目的としたAPIで、そのために、メッセージの送受信を専用のメソッドとイベントだけに限定し、送受信時に相手先のオリジンを確認できるようになっています。
渡すメッセージに、子フレームのコンテンツの高さを入れてやろうって事です!
子フレームから親フレームにメッセージを渡す
子フレームにpostMessageを実装する
まず、子フレームにて、親フレームに渡すコンテンツの高さとスクロール位置を文字列にして渡します。
// ウィンドウload時のイベントで
window.addEventListener("load", postSize, false);
function postSize(e){
var target = parent.postMessage ? parent : (parent.document.postMessage ? parent.document : undefined);
if (typeof target != "undefined") {
target.postMessage("height"+document.body.scrollHeight+"_top100", "https://example.com");
}
}
// または、何かしらのアクションでのイベントで
function doEntry() {
var target = parent.postMessage ? parent : (parent.document.postMessage ? parent.document : undefined);
if(typeof target != "undefined"){
target.postMessage("height"+document.getElementById('entryResult').scrollHeight+"_top0", "https://example.com");
}
}
- 親フレームがpostMessageを使えるかチェックします。
var target = parent.postMessage ? parent : (parent.document.postMessage ? parent.document : undefined);
- postMessageでメッセージを送る
target.postMessage("height"+document.body.scrollHeight+"_top100", "*");
param | 意味 |
---|---|
message | 他のウィンドウに送られる文字列データ |
targetOrigin | 自身のURIか、 "*" というリテラル文字列(指定しないことを示します)で指定します。もしイベントが targetOrigin で指定されたものにマッチしない場合、そのイベントは伝達されません。 |
詳しくはこちら |
親フレームにmessageイベントを受け取れるようにする
以下の例は、ウィンドウの高さとスクロールの位置をmessageから受け取る例です。
// messageのイベントリスナー
window.addEventListener("message", receiveSize, false);
// 実行関数
function receiveSize(e) {
// e.dataに「height1000_top0」のような文字列が入ってくる想定。
var data = e.data.split('_');
// originのチェック。
if (e.origin === "https://example.com" && (0 == data[0].indexOf("height") && (0 == data[1].indexOf("top")) ) {
document.getElementById("entryform").style.height = parseInt(e.data.replace('height', '')) + "px";
// FirefoxとIE11で動かなかったので一部修正
$('html, body').scrollTop(parseInt(data[1].replace('top', '')));
}
}
messageを受け取ったら、
window.addEventListener("message", receiveSize, false);
でreceiveSize()
を呼び出します。
イベントデータのプロパティは以下です。
プロパティ | 意味 |
---|---|
data | postMessageで送ったmessage部分 |
origin | postMessageで送ったtargetOrigin部分 |
セキュリティ上、if (e.origin === "https://example.com")
でURIのチェックは行った方がよさ気です。
はい、以上で子フレームのコンテンツの高さを親に渡す事ができました。
他に良い方法があれば教えて下さい(・∀・)