🕶️

【javascript】iFrameの高さを動的に変える方法

に公開

はじめに

大手SIerでWEBアプリエンジニアとして働くNaotoです!
今回は画面でiFrameを使った際に私が躓いた内容と解決方法を共有させていただきます!!

iFrameの高さが固定されて微妙。。。

iFrameでコンテンツを画面内に組み込む際によく直面する問題として、高さ制御が挙げられます。iFrameの高さは特に指定していない場合、内部のコンテンツがレンダリングされたタイミングで自動調整してくれます。
ですが、内部のコンテンツにドリルダウンやアコーディオンなどの動的要素があった場合、無駄な余白が生じたり、高さが足りずにiFrame内でスクロールが発生してしまいます。
今回は、そんな少し曲者のiFrameについて、内部のコンテンツの状態に応じて動的に高さを調整する方法を共有します!!

用語説明

以降、以下の用語を使って説明します。

  • 呼び出し元:iFrameタグを埋め込んでいるHTMLファイル
  • 呼び出し先:iFrameタグの中で表示しているHTMLファイル

制御方法

制御方法を言葉で説明すると、

  1. 呼び出し先において、特定のイベントの発火時に呼び出し元に自コンテンツの高さを送る
  2. 呼び出し元において、メッセージをキャッチした際に内容を解析してiFrameの高さを変更する
    という手順で、呼び出し元と先とで情報連携しながら動的制御をしていきます。

具体的なコード

呼び出し先

呼び出し先のHTML用にJSで以下のようなfunctionを定義します。
init()が実行されることで、初期の高さ調整と、DOMの変更を検知した高さ調整が可能となります。
※ DOMの変更が検知されない場合、各イベントごとに個別sendHeightToParentメソッドを呼べば問題ありません。

// 高さ取得および呼び出し元への送信メソッド
function sendHeightToParent() {
  // 要素のスクロール高さを取得
  const height = document.body.scrollHeight;

  // 呼び出し元に高さをメッセージとして送る
  window.parent.postMessage({type: "setHeight", height: height}, window.location.origin)
}

// MutationObserverを設定して、DOMの変更を監視
function observeDOMChanges() {
    const observer = new MutationObserver(sendHeightToParent);
    observer.observe(document.body, { childList: true, subtree: true });
}

// 初期化処理
function init() {
  // 初期表示タイミングの高さ調整
  sendHtightToParent();

  // DOMの変更を監視
  observeDOMChanges();
}

呼び出し元

メッセージを受け取った際にiFrameの高さに関するスタイルを変更するイベントを定義しておきます。

// iFrameのコンテンツからメッセージを受け取ったときのイベント処理
window.addEventListener("message", function(event) {
  // メッセージの送信元を確認
  if (event.origin !== window.location.origin) return;

  // iFrameの高さ調整
  const data = event.data;
  if (data.type === "setHeight" && data.height) {
    const contentFrame = document.querySelector("#contentFrame");
    if (contentFrame) {
      // ここでiFrameの高さを指定
      contentFrame.style.height = (data.height + 50) + "px";
    }
  }
}, false);

このように、呼び出し元と呼び出し先とで値を連携することで、iFrameの高さに関する動的制御は容易く行えます。
postMessageをうまく使えば、他の連携処理も楽に記述できそうですね♪

最後に

今回は、iFrameを使用する際の動的制御について共有させていただきました。レスポンシブなデザインが必須となりつつある現代において、動的制御に目を背けてはいけませんね笑。私もこの課題にぶち当たったことで改めて痛感いたしました(・_・;) 閲覧いただきありがとうございました!!

Discussion