読者です 読者をやめる 読者になる 読者になる

ECのウェブ担当者のメモ

ECサイトを運営管理している、WEB担当プログラマのメモ

スポンサーリンク

iframeの子の高さを親に伝える方法。しかもクロスドメイン

f:id:jun9632:20151114015831j:plain

表題の件になります。

iframeの子の高さを親に伝える方法です。

つまり、親の画面で、iframeを使って子供の高さがわからないから、 余分な余白とかスクロールがでたらみっともないから、ちゃんとしたサイズで 表示しましょうという話です。

わかりますよ。言いたいことは。

そもそも、iframe使ってるんじゃないよ!っと気持ち。 さらに、クロスドメインで。

私だって、もしそんな提案を持ちかけられたら、 「なんでこんなことしないといけないんですかぁ〜????」 って聞いちゃうと思います。

でもね。

大人の事情もあって、時にはやらないと行けない時もあるんです。

そんな時のために、これから本題に入ります。

概要

実装の概要ととして、

子供(iframeの中)から親(irameを読んでる場所)に高さを伝えて、 親は、よしわかったその高さね!っという感じで高さを設定します。

その時、子供は、messageをpostして、親はそのメッセージを受け取ります。

以下に、実際の実装内容です。

子供側の実装

子供側からは、親に向けて自分の高さ(scrollHeight)を、 親に向けて、メッセージとして送信します。

ロード時のリサイズ時にEventListenerで、postSizeを呼び出すようにしています。 loadは初期ロード時に、resizeはサイズが変更した時を想定しています。

サイズが変更するときは、つまり高さが変更するときなんんですが、 最近の感じとして、レスポンシブルになっているので、ウィンドウを縮めて言った時に 回りこんで高さが増えたり、逆に広げていった時に、高さが減ってしまうことがあり、 そんな条件を想定しています。

コードは以下のようになります。

<script type="text/javascript">

 window.addEventListener("load", postSize, false);
 window.addEventListener("resize", postSize, false);
 function postSize(e) {
    var target = parent.postMessage ? parent : (parent.document.postMessage ? parent.document : undefined);
    if (typeof target != "undefined" && document.body.scrollHeight)
      target.postMessage(document.getElementById("your-contents").scrollHeight, "*");
  }
  
</script>

親側の実装

親側は、子供から投げられた高さを取得して、iframeの高さを設定します。

取得&設定は以下のようになります。

if (e.origin === "http://[your-domain.com]") では、 余分なメッセージを拾わないように、子供のドメインを指定します。

<script type="text/javascript">

//iframeの高さ調整ここから
  window.addEventListener("message", receiveSize, false);
  function receiveSize(e) {
    if (e.origin === "http://[your-domain.com]") {
      $('#your_iframe').height(e.data);
    }
  }
//iframeの高さ調整ここまで

</script>

まとめ

普段Railsを使っているので、高さを設定するgemもあったりして、ちょっと試して見たりもしましたが、 結果的に上記の方法に落ち着きました。

クロスドメインだと、逆にシンプルな形になると思われます。

根本がおすすめ出来ない内容ですが、否応無く実装しないと行けない時は なくなく、ためしてみてください。