楽天RMS スマホサイトでiframeの高さを自動調整しよう

楽天市場へ出店している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ファイルを要する必要があるため、一括での管理をお勧めします。

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

よかったらシェアしてね!

この記事を書いた人

フロントエンドエンジニア/星のソムリエ®
お酒と紅茶とチョコレートが大好きです。

コメント

コメント一覧 (37件)

  • getiframe_allを編集し、GOLDにアップロードまでは解ったのですが、商品ページに掲載したい場合、商品ページのiframeを表示させたい任意の場所にを記載するという認識でよろしいのでしょうか。そのように記載したところiframeが表示されず、を掲載する場所の問題なのか、そうではなく、iframeを表示させたい場所には何か記載しなければいけないといことなのでしょうか…..。

  • こんにちは。
    試してみましたが、iframeが表示されません。
    現在はこの方法は使えなくなっていますでしょうか?

  • 参考にさせていただいております。
    が、やはり私もiframe表示されないのです。。
    https://tools.tada-fla.com/getiframe/ も確認しましたが、

    3.アップしたjsファイルをページへ読み込む
    の「読み込む」とは具体的にどのような作業になりますでしょうか?

    このページの具体的な手順はすべて踏んで、リンク先URL等も間違いがないか何度もチェックしたのですが。。。

    • ありがとうございます。
      「読み込む」とは、商品ページ、カテゴリページの共通説明文に

      こちらのコードを記入することです。

      iframeそのものが表示されないということでしょうか?

      • 返信ありがとうございます。
        もう一度ゆっくり順を追ってひとつづつやってみたところ、うまく表示できました!ありがとうございます。シンプルなタグでスマートです、感謝いたします。

        • ご報告、ありがとうございます!
          おめでとうございます!
          素敵な商品ページ作りに役立てば幸いです!

  • 「商品Aページ内に読み込むjsファイル」「一括管理用のjsファイル」両方を同時に効かせることはできるのでしょうか?楽天のある商品ページ(スマホ)内に2つiframeを設置しています。ひとつは、全商品に共通するiframeです。ひとつは、商品ごとやカテゴリーごとに固有のiframeです。全商品に共通するiframeに対して「商品Aページ内に読み込むjsファイル」内にgetElementById(“iframe-box”)と記述しiframeを表示させ、「一括管理用のjsファイル」内にはgetElementById(“iframe-box-all”)と記述しiframeを表示させ、1ページ内でふたつのiframeを表示させようとしていますがうまくいきません。※どちらかひとつに絞ればうまくいきますが、両方同時に表示できないのです。2つのjs内で同じような箇所が見受けられるので、そこがエラーになっているんでしょうか?ご返信いただければ幸いです。よろしくお願いします。

    • ありがとうございます。
      おっしゃるように両方同時に高さ調整をしようとすると、このままではできません。
      どちらか一つしか表示されないというのは、iframeそのものがどちらかしか表示されないということでしょうか、それとも高さの自動調整が片方にしか効かないということでしょうか。

      表示についてですが、
      getElementById(“iframe-box”)
      これは #iframe-box をに対しての指示なので、商品ページ側でもこれに合わせてdivのidを変えてあげないといけません。
      こちらは問題ないでしょうか?

      2つのiframeの高さの調整に関しては、jsファイルの内容を書き換えないといけないので、申し訳ございませんがこちらのコメント欄での対応はいたしかねます。
      詳細をご連絡いただけましたらお見積りいたしますのでご一考くださいませ。

      • ご返信ありがとうございます。

        どちらか一つしか表示されないというのは、iframeそのものがどちらかしか表示されないということでしょうか、それとも高さの自動調整が片方にしか効かないということでしょうか。
        ↑↑↑
        片方のiframeは高さ調整できている状態で表示され、もう片方のiframeは高さ調整できていない状態(途中で切れている)で表示されます。かつ、ページが明滅されていて、明らかにバグっている状態です。

        getElementById(“iframe-box”)
        これは #iframe-box をに対しての指示なので、商品ページ側でもこれに合わせてdivのidを変えてあげないといけません。こちらは問題ないでしょうか?
        ↑↑↑
        getiframe_single.jsではIDをiframe-boxとし、getiframe_all.jsではIDをiframe-box-allとして商品ページ内で2か所とに分けて指示しましたが、片方の自動調節しか効かないようです。

        iframeで読み込むGoldページへの記述
        (function(){
        function iframeHeight(){
        var h = ‘iframeheight’;
        window.parent.postMessage(h,’*’);
        }
        setInterval(iframeHeight, 500);
        })();
        表示させる子iframeが複数(今回は2か所)ある場合、呼び込むときにエラーとなってしまうのでしょうか?呼び込む子iframeのどちらにも効けばいいのですが。有料も検討したいのですが、納品においくらくらいかかるのでしょうか?

        • ご返信ありがとうございます。

          まず表示は行えているとのこと、ありがとうございます。
          その上のご対応ということでしたら、改めてご連絡差し上げます。

          どうぞよろしくお願いいたします。

  • いつも勉強をさせて頂いております。

    何度もトライさせていただいておりますが、
    表示がされないため、ご連絡させて頂きました。

    https://tools.tada-fla.com/getiframe/
    上記の4番まではわかるのですが、

    5番の「5.呼び出されるGoldページへコードを記述する」は
    「1.管理用jsファイルを生成する」「iframeに呼び出される楽天Goldページ」で作成したHTMLファイルに追加記述をするのでしょうか?

    また、こちらの確認不足で申し訳ございませんが、iframeページの画像等には、width=”〇〇〇” height=”〇〇〇”は記載は必要でしょうか?

    実際にRMS上でiframeの記載をするバグコードも併せてご教示いただきたいと思い、ご連絡させて頂きました。

    ご返答お待ちしております。
    宜しくお願い致します。

    • ありがとうございます。

      >5番の「5.呼び出されるGoldページへコードを記述する」は
      「1.管理用jsファイルを生成する」「iframeに呼び出される楽天Goldページ」で作成したHTMLファイルに追加記述をするのでしょうか?

      おっしゃるとおりです。
      Goldにアップするhtmlファイルに記述してください。

      また、画像のwidthとheightですが、記載があるとページのレンダリング(表示)が早くなるのであるとよいですが、なくても問題ございません。
      cssで調整するとしても、一旦入れていただければと思います。

      >実際にRMS上でiframeの記載をするバグコード

      RMS上ではiframeの記載はございません。Javascriptからタグを生成するので、
      https://tools.tada-fla.com/getiframe
      に沿ってお試しください。

  • 初めまして。
    こちらの記事を参考にさせていただいて、
    iframeを表示させるところまではできたのですが、
    幅や高さが調整されず、デフォルト?300×150で表示されてしまい、
    見切れてしまっている状態です。
    原因としては、postMessageがうまく送受信されていないのかと思うのですが、具体的にどうすればいいのかわからない状態です。
    もちろん、goldのhtmlには、</div>の直前に指定された内容の記述をしております。
    他の関係なさそうな、script要素も削除して、画像とこちらのscriptだけの最小構成にしてみてもダメでした。

    何か、他に気を付けなければならない点、修正してみる点などありましたら、ご教授願いますでしょうか。

    ※iframeの内容がそもそも表示されない方々へ。jsファイルのiframeを表示させたい商品ページのリンクURLの最後に「/」を入れてはいけません。自分も支援サイト通りにやっていたところ、「/」の削除を見落としていたので、見直してみてください。
    また、再度GOLDにjsファイルをアップしても、楽天の仕様上、画像と同じく、jsもキャッシュされており、なかなか更新されないので、即時反映したい場合は、ファイル名か階層を変えるなどしてみてください。

    • ありがとうございます。

      サイトを見ていないので原因は特定できませんが、</div>の前というのは、</body>の直前ということでよろしいでしょうか?
      もしhtmlの途中で<script>を記載しているなら、一度</body>直前へ移動させてみてください。

      コメントの補足、ありがとうございます。
      助かります!

      • 返信ありがとうございます。
        の件、失礼いたしました。</body>の間違いです。

        また、一つ確認で、
        ブラウザ上から、iframeのソースを見ると、下記のスクリプトがの前に勝手に追加されています。

        実際のHTMLファイルには上記の記述はしていないので、楽天側で勝手に挿入されているものかと思っているのですが、こちらが不具合を起こしている原因だったりするのでしょうか。
        ご確認のほど、よろしくお願いいたします。

        • ご返信ありがとうございます。
          <srcript>の記述場所は問題ないのですね。

          コメント上でエスケープされてしまっていますが、https://r.r10s.jp/で始まるURLでしたら、Goldにアップした時点で自動で入るものとなります。
          現状ではそちらとバッティングして不具合というのは起こっていませんので、別の原因かと存じます。

          よろしくお願いいたします。

          • やはり、ちょっと原因がわからない状態です。
            もし、ご対応が可能でしたら、上記の商品ページを見ていただけますでしょうか。
            iframeの位置は「レビューを書く」「ショップレビューを見る」の上部にある
            「ここからは~」という画像のやつです。

            何卒、よろしくお願いいたします。

          • ご返信が遅くなり、申し訳ございません。
            支援ツールからダウンロードするjsファイルを修正しました。
            もう一度お試しいただけますでしょうか。
            よろしくお願いいたします。

  • 初めまして。
    コメント失礼致します。
    記載いただいている方法ではまだ試させていただいてないのですが
    アンドロイドのスマホでiframeの高さが自動調節されず切れてしまう現象が起こって
    いるのですが、こちらの記載の方法ではアンドロイドのスマホでも高さ調節がきっちり
    できるのでしょうか??

    • ありがとうございます。
      古いAndroidは確認しておりませんが、4.4以降でしたら問題なく表示されます。
      ただし、ご使用は自己責任でお願いいたします。

  • はじめまして。コメント失礼いたします。
    こちらの記事を参考にして実際の商品ページにアップしました所、
    Android(Chrome)やPCでの検証画面では問題なく表示されました。
    ただ、iphoneでは表示されるものの
    アコーディオンメニューを開くと高さが可変されません。。。
    (Safari、Chromeともに同じ現象)
    (Android、PCの検証画面ではアコーディオンの開閉に合わせて高さも調整されます)
    考えられる原因はなにか、分かりますでしょうか?

    • ありがとうございます。
      こちら、検証でのiPhoneは問題ないが、実機のiPhoneでアコーディオンの高さの変化が反映されないという理解でよろしいでしょうか。

      • ご返信いただきまして、ありがとうございます。
        仰る通りです。
        実機のiphoneではSafari、Chromeともに高さが変わりませんでした。
        DW上、検証画面、Androidでは問題なく変化いたします。
        キャッシュをクリアして何度か試してみたのですがダメでした…。

        • ご返信が遅くなり、申し訳ございません。
          なるほど、そういうことですね。
          iOSの仕様なのかもしれませんが、ちょっと確認してみます。
          不具合のご連絡ありがとうございます。

  • はじめまして。有益な情報をありがとうございます。
    無事実装することができて嬉しい次第です。

    1つ質問がありますのでよろしくお願いいたします。
    例えば、A.js、B.jsと作成し楽天のカテゴリ画面で内容の違う2つのhtmlファイルを同じ画面に表示させたいのですが、2つ目のhtmlファイルの方が表示はされるのですが、点滅してしまいます。

    なぜこのような事がしたいかというと、カテゴリによって表示させたい内容は違うのですが、あるカテゴリにおいてはその両方を表示させたいと思ったからです。

    片方のhtmlファイルに内容をまとめれば問題はないと思いますが、2つのjavascriptの共存はできないものでしょうか?

    スマートフォン用カテゴリ説明文

    お忙しいところ申し訳ございませんがよろしくお願いいたします。

    • ありがとうございます。
      また、ご返信が遅くなり、申し訳ございません。
      こちらのサイト内のJavaScriptではアーツ様の考えておられることはできません。

      2つのhtmlをまとめていただき、カテゴリによって呼び出すhtmlを変えていただくという方法になります。

      一つのカテゴリページに2つ以上のiframeを呼び出したいということへのご対応は、他の方へも返答していますが、有償して承ります。
      よろしくお願いいたします。

  • 大変参考になるソースをありがとうございます。

    以前の方が同じ要望をされていましたが、同じく、同一商品ページ内の複数のiframeの高さを
    自動で調整するようにしたいと思っております。そのために、現在のソースを、複数対応にするための
    見積もりをお願いしたいのですが、

    >表示させる子iframeが複数(今回は2か所)ある場合、呼び込むときにエラーとなってしまうのでしょうか?>呼び込む子iframeのどちらにも効けばいいのですが。有料も検討したいのですが、納品においくらくらいか>かるのでしょうか?

    • ありがとうございます。
      それでは詳しい状況をヒアリングさせていただきたく存じます。
      どうぞよろしくお願いいたします。

  • 先日はご回答頂きありがとうございました。
    1ページで2種類以上のiflameを読み込むようにするにあたり
    お見積りを頂けますでしょうか?
    2種類・3種類~とお見積りが変わるようでしたら2種類でのお見積りをお願いいたします。
    2種類以上~で使えるようになると嬉しいのですが。

    どうぞよろしくお願いいたします。

    • ありがとうございます。
      それではご連絡差し上げます。
      どうぞよろしくお願いいたします。

      • 現在のところお見積りを頂いておりませんがお見積りはいつごろ出ますでしょうか?

        • 1月9日に、こちらの書き込みに使用していただいてるメールアドレスにメールを差し上げたのですが、届いておりませんでしょうか。

          • すみません。届いておりました!
            返信させて頂きましたのでご確認のほどどうぞよろしくお願いいたします。

  • 楽天RMSのiframe高さ自動調整を検索してこちらのサイトにたどり着きました!
    大変参考になるソースをありがとうございます!無事に自動調整して表示させることができました。

    以前の方が同じ要望をされていますが、私も商品ページ内にiframeを2つ配置したいと考えております。
    有償とのことですので、お見積りいただけますようお願いします。

    • ひんだれ様
      コメントありがとうございます。
      メールを差し上げましたので、ご確認くださいませ。

コメントする

目次
閉じる