楽天市場へ出店しているEC店舗さんへ送る、iframeのheightの自動調整方法です。
楽天市場のスマホページと言えば、文字数と使用できるタグの制約が非常に厳しいですよね。楽天Goldでページを作成してiframeで全体を表示させるとしても、デバイスごとにiframe内のコンテンツの高さが変わってしまうので、なんだか不格好なことにも…。

実はHTML5から、postMessageという機能で親と子のiframe間でデータを通信できるようになりました。
今回はこの機能を使用して、楽天のスマホページ内のiframeの高さを自動調整できるようにしたいと思います。

※2017年7月17日加筆・修正しました。

簡単コピペでiframeのheight自動調整機能を手に入れよう

詳しいことは置いておいて、iframeを設置してみましょう。

特定の商品ページに特定のiframeを読み込む

それでは一番簡単なパターンからご紹介します。
商品Aのページへ楽天Gold内にあるhttps://www.rakuten.ne.jp/gold/○○/iframe/a.htmlを読み込んで、iframe内をスクロールさせずにページ全体を表示させたいとします。

ここで必要なのはこちらです。

  • 商品Aページ内に読み込むjsファイル(Gold内へアップロードします)
  • 商品Aページ内の記述
  • iframeで読み込むGoldページへの記述

iframe内の子ページからデータを投げて、親ページで受け取って処理するイメージです。

商品Aページ内に読み込むjsファイル

親ページである商品Aのページで子ページのiframeデータを受け取るためのjsファイルを用意します。

(function () {(
  var url = 'https://www.rakuten.ne.jp/gold/○○/iframe/a.html';//読み込むiframeのアドレス
  var code = '<iframe src="' + url + '" scrolling="no" frameborder="0"></iframe>';
  document.getElementById("iframe-box").innerHTML = code;
})();

(function () {
  function iframeData(e) {
    var iframeValue = e.data;
    if (/iframe/.test(iframeValue)) {
      var iframeHeight = iframeValue.replace(/iframe<*(.*?)>height*/g, '$1');
      iframeHeight = Number(iframeHeight) + 30;
      var iframeBox = document.getElementById("iframe-box").getElementsByTagName("iframe")[0];
      if (iframeBox) {
        iframeBox.setAttribute('style', 'height: ' + iframeHeight + 'px; margin: 0; padding: 0; display: block; width: 100%;');
      }
    }
  }
  window.addEventListener('message', iframeData);
})();

上記内容をコピペし、2行目の読み込むiframeアドレスを書き換えてください。
このjsファイルを楽天Goldへアップします。

面倒な場合は下記ファイルをダウンロードしてください。中身は上記コードと同じです。

javascript filegetiframe_single.jsをダウンロード

同じように2行目のiframeアドレスを書き換えて楽天Goldへアップしてください。

商品Aページ内の記述

スマートフォン用商品説明文

RMS>1-1 商品登録更新から、商品Aの商品個別編集ページへ行き、スマートフォン用商品説明文に下記コードを加えます。

<div id="iframe-box" =""></div ="">
<script src="https://www.rakuten.ne.jp/gold/○○/xxxx.js" ="">
</script              >

上記<script>タグ内のアドレスは先ほどアップしたjsファイルの場所を指定してください。

iframeで読み込むGoldページへの記述

iframeで呼び出されるGoldページの</body>直前に<script></script>タグを加え、その中に下記コードを挿入します。

(function(){
  function iframeHeight(){
    var h = 'iframe<' + document.body.clientHeight + '>height';
    window.parent.postMessage(h,'*');
  }
  setInterval(iframeHeight, 500);
})();

これでiframeの高さが自動調整されて表示されたと思います。

ちょっと準備が面倒ですが、文字数や画像数を気にせずページを作り込めるメリットは大きいです。

全てのiframeを一括で管理したい

とりあえず商品ページに呼び出すiframeを自動調整することはできました。
しかし、一つずつ先ほどの方法でページに挿入していくのは合理的ではありません。また、カテゴリページの説明文内にはどう頑張っても<script>タグを挿入できないので、この方法は使えません。

そこで、商品ページやカテゴリページの共通説明文内に<script>タグを埋め込み、あらかじめ「iframeを設置したいRMSページ:iframeで呼び出されるGoldページ」の一覧を用意して、対応するiframeページが存在するときのみ呼び出すようにして、一括で管理してしまいましょう。

現在のページにiframeで呼び出す内容があるときのみ処理する

高さ調整の必要があるiframeを呼び出す商品ページとカテゴリページ、それに対応するiframeのアドレスの一覧を用意して、現在のページがその条件に当てはまるときのみ処理をするようにします。
これなら、一括で管理するjsファイルを書き換えるだけの手間で済みます。

ここで必要になるのはこちらです。

  • 一括管理用のjsファイル(Gold内へアップロードします)
  • スマホの共通説明文の記述
  • iframeを読み込む商品ページ・カテゴリページの記述
  • iframeで読み込むGoldページへの記述

一括管理用のjsファイル

今回は現在のページに対応するiframeが存在するときだけ指定の場所へiframeを呼び出すjsファイルを用意します。

(function () {
  var urls = { //対応するRMSページとGoldページ
    'https://item.rakuten.co.jp/○○/c/0000000000': 'https://www.rakuten.ne.jp/gold/○○/iframe/a.html',
    'https://item.rakuten.co.jp/○○/aaa-000': 'https://www.rakuten.ne.jp/gold/○○/iframe/aaa-000.html'
  };

  var locateUrl = window.location.href.replace('http:', 'https:').split('?');
  var nowUrl = locateUrl[0];
  if (nowUrl.slice(-1) == '/') {
    nowUrl = nowUrl.substr(0, nowUrl.length - 1);
  }
  if (nowUrl in urls) {
    var code = '<iframe src="' + urls[nowUrl] + '" scrolling="no" frameborder="0"></iframe>';
    document.getElementById("iframe-box").innerHTML = code;
  }
})();

(function () {
  function iframeData(e) {
    var iframeValue = e.data;
    if (/iframe/.test(iframeValue)) {
      var iframeHeight = iframeValue.replace(/iframe<*(.*?)>height*/g, '$1');
      iframeHeight = Number(iframeHeight) + 30;
      var iframeBox = document.getElementById("iframe-box").getElementsByTagName("iframe")[0];
      if (iframeBox) {
        iframeBox.setAttribute('style', 'height: ' + iframeHeight + 'px; margin: 0; padding: 0; display: block; width: 100%;');
      }
    }
  }
  window.addEventListener('message', iframeData);
})();

上記内容をコピペし、3行目以降のiframeを読み込みたい商品ページまたはカテゴリページのアドレス、iframe内に呼び出されるページのアドレスへと書き換えてください。
‘RMSページ’:’Goldページ’を,(カンマ)区切りでどんどん記入していきます。最後の行にはカンマを入れないようにしてください。
このjsファイルを楽天Goldへアップします。

面倒な場合は下記ファイルをダウンロードしてください。中身は上記コードと同じです。

javascript filegetiframe_all.jsをダウンロード

同じように3行目以降のiframeアドレス一覧を書き換えて楽天Goldへアップしてください。

スマホの共通説明文の記述

商品ページの場合

スマートフォン用商品ページ共通パーツ設定
RMS>1-2 デザイン設定>2 スマートフォンデザイン設定>商品ページ共通パーツ設定から、商品ページ共通説明文に下記コードを加えます。

<script src="https://www.rakuten.ne.jp/gold/○○/xxxx.js" ="">
</script              >

上記<script>タグ内のアドレスは先ほどアップしたjsファイルの場所を指定してください。

カテゴリページの場合

スマートフォン用カテゴリページ共通パーツ設定
RMS>1-2 デザイン設定>2 スマートフォンデザイン設定>カテゴリページ共通パーツ設定から、カテゴリページ共通説明文に下記コードを加えます。

<script src="https://www.rakuten.ne.jp/gold/○○/xxxx.js" ="">
</script              >

上記<script>タグ内のアドレスは先ほどアップしたjsファイルの場所を指定してください。

iframeを読み込む商品ページ・カテゴリページの記述

商品ページの場合

スマートフォン用商品説明文
RMS>1-1 商品登録更新から、iframeを設置したい商品の商品個別編集ページへ行き、スマートフォン用商品説明文に下記コードを加えます。

<div id="iframe-box" =""></div ="">
カテゴリページの場合

スマートフォン用カテゴリ説明文
RMS内1-1 商品登録更新>2 カテゴリページ設定>店舗内カテゴリ設定からiframeを設置したいカテゴリを選択して「カテゴリページ編集」で変種画面に入り、スマートフォン用カテゴリ説明文へ下記コードを加えます。

<div id="iframe-box" =""></div ="">

iframeで読み込むGoldページへの記述

iframeで呼び出されるGoldページの</body>直前に<script></script>タグを加え、その中に下記コードを挿入します。

(function(){
  function iframeHeight(){
    var h = 'iframe<' + document.body.clientHeight + '>height';
    window.parent.postMessage(h,'*');
  }
  setInterval(iframeHeight, 500);
})();

こちらは個別呼び出しの時と同じ内容です。
これで今日からあなたの店舗でもスマホページでiframeを使い放題です!!
※設置、使用はすべて自己責任にてお願いいたします。

どういう処理をしているのか

個別商品での処理も、一括での処理もやっていることは同じです。

  • 親ページにiframeの受け皿を用意しています(<div id=”iframe-box”>の部分です)。
  • 親ページに設置してあるjsが、#iframe-box内にiframeタグを設置し、子ページをその中に呼び出します。
    ちなみに、親ページに直接iframeタグを書かないのは、ページごとに記入する方法に差があるからです(divも含めて禁止タグなので、設置の方法が特殊です)。
  • 呼び出された子ページ内にあるjsが、自分の高さを親ページへ通信します。
  • 親ページのjsが、子ページから通信された高さをiframeの高さに反映します。

ざっくりこのような処理を行っています。
必要なものは親ページのjs、子ページのjs、親ページの受け皿の三つです。

商品ごとに設置する場合は、それぞれの商品ページごとのjsファイルを要する必要があるため、一括での管理をお勧めします。

分かりにくい点などがあれば、コメントいただけると修正・追記しますのでよろしくお願いします。