プログラムをiframe、またはAjaxで組み込んだ際の違い


既存のページ内に何らかのプログラム、例えば当サイトで配布しているカレンダー新着情報欄の更新システムなどを組み込むとき、iframe方式で組み込む方法とAjax方式で組み込むやり方が考えられます。

それぞれ一長一短があり、どちらのやり方でページ内に組み込めるようにするかはそのプログラムを作った人の思想によります。

ちなみに当サイトで配布しているプログラムでは、既存ページ内への組み込みは基本的にAjax方式を前提として作っています。iframeではデメリットがあるからです。
その点について、このページでは具体例を挙げて解説していきます。

既存のページ内にカレンダーを組み込む例

例えば、以下のような既存のページがあると仮定し、このページ内にカレンダープログラムを組み込むとします。
カレンダーを組み込んだ際にそれぞれの境界がわかりやすくなるよう、ページ全体を赤色にしています。
組み込むページ

iframeでページ内に組み込むと以下のようになります。
iframeでページ内に組み込み

それに対し、Ajaxでページ内に組み込むと以下のようになります。
Ajaxでページ内に組み込み
見てわかるように、この時点ではどちらの方式で組み込んだとしても見た目に違いはありません。

カレンダーの縦幅が変化した場合、どうなるか?

例えば、2021年の1月や5月はカレンダーの日付の行が6行になります。(曜日表示の行も含めると合計7行)
つまり、カレンダーの縦幅が増します。
するとどうなるか?

iframeで組み込んでいる場合、2021年1月の表示は以下のようになってしまいます。
縦幅が増した分、表示領域からはみ出してしまい、スクロールバーが出現してしまっています。(「定休日」の文字がはみ出ている)
縦幅が変わった時のiframeの表示
例えばCSSで「overflow:hidden;」などを指定しておけばスクロールバーの出現を防ぐことはできますが、カレンダーが表示領域からはみ出ることを防ぐことはできません。

それに対し、Ajaxで組み込んでいる場合の2021年1月の表示は以下のようになります。
カレンダーの縦幅が増しても、表示領域が自動的に広がっていることがわかります。
縦幅が変わった時のAjaxの表示

表示領域からはみ出てしまう原因

iframeは上で紹介した例のように、公開するページ(以下、親ページと呼ぶ)の中にカレンダーのページ(以下、子ページと呼ぶ)を組み込む仕組みです。
iframeの仕組み

その際、表示領域の大きさは親ページ側であらかじめ設定しておく必要があります。(CSSやHTMLなどで)
表示領域の設定
このような仕組みですので、もし子ページ側の縦幅や横幅が変わった場合は、親ページ側の表示領域をはみ出てしまうのです。

上の例では「カレンダーの行が増えた場合」の例でしたが、もし「行が減った場合」は以下のように不要なスペースが発生してしまうことになります。
縦幅が減った場合の表示

もし、子ページの大きさ(幅や高さ)に合わせて親ページの表示領域が変わるようにしたい場合はHTMLとCSSだけでは実現できないため、JSを使ってゴニョゴニョやる必要があります。

しかしどうせJSを使うのであれば、Ajaxを使って組み込むほうがスマートです。
上で挙げた例のように、Ajaxで表示させる場合は子ページの大きさに合わせて親ページの表示領域が自動的に変化するからです。
親ページでの表示領域を自動調整するためのコード自体がそもそも不要です。

そのような理由から、当サイトで配布しているカレンダー新着情報欄の更新システムはAjax方式でのページ組み込みを前提として作られています。

(余談1) 親ページと子ページのデザイン設定について

また、これはデメリットというほどのことではないですが、iframeの場合は親ページのデザインは親ページ側で、子ページのデザインは子ページ側で設定する必要があります。
つまり、CSSが分散してしまう可能性があります。(HTMLとCSSの設計にもよりますが)

しかし、Ajaxの場合は子ページ側のデザインも全て親ページ側で設定する仕組みです。
親ページ内で子ページを表示させるわけですから、そのほうが直感的に設定しやすい面があります。

(余談2) 表示領域が調整されるタイミングについて

以下はさらにマニアックな話になりますので、興味のある方以外は読む必要は特にありません。

iframe方式での表示の際、子ページの大きさに合わせて親ページ側の表示領域を自動調整するためにはJSで行う必要があると説明しました。

そのJSが実行されるタイミング、つまり親ページでの表示領域が自動調整されるタイミングは「load」イベント以降になるでしょう。
そうしないと子ページの大きさが正常に取得できないからです。

ページが表示される過程の中で「load」イベントはかなり遅いタイミングです。
それまでは親ページ内の表示領域は大き過ぎたり小さ過ぎたり、サイズが合っていない状態になります。

それに対し、Ajax方式なら表示領域の設定自体が不要なので、もっと早いタイミングで子ページを正しいサイズで表示させることができます。
一般的には「DOMContentLoaded」イベントで表示させることが可能でしょう。
つまりloadイベントよりずっと早いタイミングになります。

提供サポートなど