iframeで埋め込み元の高さ計算して埋め込み先に反映させる方法
HTMLのインラインフレーム要素(iframe)で、他サイトのページを埋め込むアイデアはわりとよく使われます。TwitterやFacebookのウィジェットなんかも、iframeで埋め込んでいますよね。
私たちが使う場合では、異なるサービス間でコンテンツをやり取りしたい場合でしょうか。
たとえば、カラーミーショップ(EC)にWordPressのコンテンツを埋めこんだり。
やってみると意外に難しい場面に遭遇しますが、その点について解説します。
iframe埋め込みで注意すること
埋め込む先が常時SSLの場合は、埋め込み元サイトもSSL化しておく必要があります。
サーバー設定によっては、iframeで埋め込めないこともあります。
昨今はレスポンシブサイトに埋め込むことが多いと思います。横幅に対してコンテンツが可変しますので、埋め込みページの高さが増減することがあります。
また動的なコンテンツを埋め込む場合も高さは変化します。
高さが変化しないような埋め込みは高さを固定で指定して問題ありません。
高さが変化する場合は下が切れたりするので、高さ調整を行う必要があります。
その部分の作りが、初心者の方にとってはむずかしいです。
コード解説
埋め込み元、埋め込み先、どちらにもコードを書きます。
埋め込み元
コード
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(window).on('load resize', function(){
setTimeout(function(){
var height = $('body').height();
window.parent.postMessage(height, 'https://埋め込み先.com');
},500);
});
</script>
埋め込み元では、$('body').height() で高さ計算します。
window.postMessage() で埋め込み先に高さを送信します。Window オブジェクト間で安全にクロスドメイン通信を可能にするためのメソッドです。
setTimeout() は、高さ計算前にどの程度待ち時間を入れるかです。動的なコンテンツの場合、待ち時間がある程度ないと正確な高さが取得できません。ゼロで問題ない埋め込みもあります。
埋め込み先
コード
<div>
<iframe style="width:100%; height:1px; display:block; margin: auto auto; border:none;" class="child-iframe" src="https://埋め込み元.com/contact.html" scrolling="no"></iframe>
</div>
<script>
$(function(){
$(window).on('message', function(event){
// 末尾にスラッシュをつけるとエラーになるので注意
if (event.originalEvent.origin != 'https://埋め込み元.com') return;
$('.child-iframe').css({
'width': '100%',
'height': event.originalEvent.data
});
});
});
</script>
$(window).on('message')で、window.postMessage()で送信したメッセージを受け取っています。
その後、css()メソッドで、iframeの高さをセットしています。
event.originalEvent.originには送信元が入っていて、正しい送信元かチェックしています。このチェックがないと、全然関係ないサイトからでも埋め込み先にメッセージを送れるんですね(セキュリティ上の問題が発生する)。
うまく動作しない場合はconsole.log()を使って、if文がうまく条件クリアできているかを確認し、さらにheightの計算が正常に終わっているかを見て、setTimeout()の待ち時間を調整すればよいです。
おわりに
iframeで埋め込みって、機能設置の際に意外とよく検討します。
読み込みに少し時間が必要なので、別案があるときはそちらも併せて検討します。
あたまに入れておくと、Webサイト制作の役に立ちます。
執筆者
えいじ@naeco.jp この記事を書いた人
自作するのが好きですぐに試したくなる、凝り性なWebエンジニア。
カラーミーショップ、モールなどのECについて記事にしています。
ご相談・お問い合わせはこちら