HTMLの共通部分を部品にして使い回す方法

未分類
この記事は約19分で読めます。

HTMLでサイトを作成するとき、何度も出てくる同じ記述を色々なファイルにコピペするのは手間です。さらにその部分を変更したくなった場合には全てのファイルを変更しなければなりません。

このような事態を避けるため、同じ記述は共通化して管理や変更を行いやすくしましょう。

共通化の考え方

基本的にあるHTMLファイルに別のHTMLファイルを読み込むことで実現します。

実際のHTMLファイルを使いながら詳しく解説していきます。

具体例

例えば、以下のようなトップページと小説一覧ページがあるとします。

index.html(トップページ)
<!doctype html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <title>トップページ</title>
  </head>

  <body>

    <header>
      <nav>ナビゲーションメニュー</nav>
    </header>

    <main>
      <p>トップページの内容</p>
    </main>

    <footer>
      <div>フッター</div>
    </footer>

  </body>

</html>
novel.html(小説一覧ページ)
<!doctype html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <title>小説一覧ページ</title>
  </head>

  <body>

    <header>
      <nav>ナビゲーションメニュー</nav>
    </header>

    <main>
      <p>小説一覧ページの内容</p>
    </main>

    <footer>
      <div>フッター</div>
    </footer>

  </body>

</html>

この2つのファイルでheaderタグやfooterタグの内容は同一であり、他のページでも変化しない共通部分であると判断できます。こうした場合にはまずこの共通部分を別のファイルに切り出します。

共通部分を別のファイルに切り出す

headerタグとfooterタグの内容だけを記述したHTMLファイルを新たに2つ作成しました。

header.html
<header>
  <nav>ナビゲーションメニュー</nav>
</header>
footer.html
<footer>
  <div>フッター</div>
</footer>

共通部分を読み込む

あとは作成したこのheader.htmlfooter.htmlindex.htmlnovel.htmlで読み込むだけです。

index.html
<!doctype html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <title>トップページ</title>
  </head>

  <body>

  <!--header.htmlを読み込ませる記述(※後に解説)--> 

    <main>
      <p>内容</p>
    </main>

    <!--footer.htmlを読み込ませる記述(※後に解説)--> 

  </body>

</html>
novel.html
<!doctype html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <title>小説一覧ページ</title>
  </head>

  <body>

  <!--header.htmlを読み込ませる記述(※後に解説)--> 

    <main>
      <p>内容</p>
    </main>

    <!--footer.htmlを読み込ませる記述(※後に解説)--> 

  </body>

</html>

このような構造にすればindex.htmlnovel.htmlheader.htmlfooter.htmlを参照するようになり、header.htmlを編集するとどちらのファイルにもheaderタグの変更が反映される仕組みです。

これがあるHTMLファイルに別のHTMLファイルを読み込むことによる共通化です。

別のHTMLファイルを読み込む方法

HTMLファイルを読み込むには様々な方法があります。前項共通化の考え方で使用したHTMLを使って、実際に動作する形にしてみます。

index.htmlnovel.htmlheader.htmlfooter.htmlの各ファイルは全て同じフォルダ内に配置されているものとします。

PHPを使用する

PHPで読み込む場合はinclude文を使用します。例えばheader.htmlを読み込む際は下記のように記述します。

<?php include "header.html" ?>

index.htmlの拡張子をindex.phpに変更しておきましょう。使用しているサーバーによっては拡張子がhtmlの場合にPHPのコードが動作しないことがあります。

index.php(完成)
<!doctype html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <title>トップページ</title>
  </head>

  <body>

  <?php include "header.html" ?> 

    <main>
      <p>内容</p>
    </main>

    <?php include "footer.html" ?>

  </body>

</html>

SSIを使用する

SSIで読み込む場合は#includeを使用します。filevirtualの指定方法がありますが、fileをおすすめします。

<!--#include file="header.html" -->
<!--#include virtual="header.html" -->

fileとvirtualの違いはファイルの探索開始位置です。

fileは、そのHTMLファイル(この場合index.html)が存在するフォルダ以下から読み込むべきファイルを探し、上の階層のフォルダを探索できません。

virtualはドキュメントルートから読み込むべきファイルを探します。

index.html(完成)
<!doctype html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <title>トップページ</title>
  </head>

  <body>

  <!--#include file="header.html" -->

    <main>
      <p>内容</p>
    </main>

    <!--#include file="footer.html" -->

  </body>

</html>

JavaScriptを使用する

JavaScriptの場合はタグを用意する方法と用意しない方法の2種類の方法があります。

タグを用意する方法

読み込ませたい位置にid属性を持ったdivタグを設置します。

index.html
<!doctype html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <title>トップページ</title>
  </head>

  <body>

  <div id="header"></div>

    <main>
      <p>内容</p>
    </main>

    <div id="footer"></div>

  </body>

</html>

このdivタグの中にheader.htmlの内容を読み込むことになります。具体的にはinnerHTMLを使用した下記のJavaScriptを使用します。

fetch("header.html")
  .then((response) => response.text())
  .then((data) => document.querySelector("#header").innerHTML = data);

このJavaScriptも外部に切り出せますが、今回は簡単にhtmlファイルの中にscriptタグで記述してみます。すると完成形はこのようになります。

index.html(完成)
<!doctype html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <title>トップページ</title>
  </head>

  <body>

  <div id="header"></div>

    <main>
      <p>内容</p>
    </main>

    <div id="footer"></div>
    
    <script>
      fetch("header.html")
        .then((response) => response.text())
        .then((data) => document.querySelector("#header").innerHTML = data);
      fetch("footer.html")
        .then((response) => response.text())
        .then((data) => document.querySelector("#footer").innerHTML = data);
    </script>

  </body>

</html>
タグを用意しない方法

すでにあるタグのどれかに注目してその前後に導入します。

JavaScriptでこれを行うにはinsertAdjacentHTMLを使用します。MDNのドキュメントを参考に構文と使い方を見ていきましょう。

・構文

element.insertAdjacentHTML(position, text);

第一引数のpositionには4つの値を入れることができます。

‘beforebegin’
element の直前に挿入

‘afterbegin’
element 内部の、最初の子要素の前に挿入

‘beforeend’
element 内部の、最後の子要素の後に挿入

‘afterend’
element の直後に挿入

https://developer.mozilla.org/ja/docs/Web/API/Element/insertAdjacentHTML

それぞれの位置を可視化するとこうなります。

<!-- beforebegin -->
<p>
<!-- afterbegin -->
foo
<!-- beforeend -->
</p>
<!-- afterend -->

例えば、index.htmlでheaderを導入したい位置は10行目です。この位置はmainの開始タグの'beforebegin'、またはbodyの開始タグの'afterbegin'であると表現できます。

index.html
<!doctype html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <title>トップページ</title>
  </head>

  <body>

    <main>
      <p>内容</p>
    </main>

  </body>

</html>

よって下記のどちらかでheaderを導入することが可能です。

fetch("header.html")
  .then((response) => response.text())
  .then((data) => document.querySelector("main").insertAdjacentHTML('beforebegin', data));
fetch("header.html")
  .then((response) => response.text())
  .then((data) => document.querySelector("body").insertAdjacentHTML('afterbegin', data));

footerはどうでしょうか?

index.html
<!doctype html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <title>トップページ</title>
  </head>

  <body>

    <main>
      <p>内容</p>
    </main>

  </body>

</html>

14行目はmainの終了タグの'afterend'、あるいはbodyの終了タグの'beforeend'です。

fetch("footer.html")
  .then((response) => response.text())
  .then((data) => document.querySelector("main").insertAdjacentHTML('afterend', data));
fetch("footer.html")
  .then((response) => response.text())
  .then((data) => document.querySelector("body").insertAdjacentHTML('beforeend', data));

HTMLの構造によって適切だと思われる引数を用いましょう。今回はscriptタグを導入するため、footerはmainの終了タグに着目して'afterend'を使用しました。

index.html(完成)
<!doctype html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <title>トップページ</title>
  </head>

  <body>

    <main>
      <p>内容</p>
    </main>

    <script>
      fetch("header.html")
        .then((response) => response.text())
        .then((data) => document.querySelector("body").insertAdjacentHTML('afterbegin', data));
      fetch("footer.html")
        .then((response) => response.text())
        .then((data) => document.querySelector("main").insertAdjacentHTML('afterend', data));
    </script>

  </body>

</html>

jQueryを使用する

JavaScriptの場合と構文が異なるだけで考え方は同じです。headタグ内でjQueryを読み込む必要がある点だけ注意してください。

タグを用意する方法

loadメソッドで可能です。

index.html(完成)
<!doctype html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
    <title>トップページ</title>
  </head>

  <body>

  <div id="header"></div>

    <main>
      <p>内容</p>
    </main>

    <div id="footer"></div>
    
    <script>
      $(function() {
        $("#header").load("header.html");
        $("#footer").load("footer.html");
      });
    </script>

  </body>

</html>
タグを用意しない方法

getメソッドでHTMLファイルを取得し、bodyタグ内に導入します。

位置の指定にはprependメソッドappendメソッドを使用します。それぞれを可視化すると次のようになります。

<p>
<!-- $('p').prepend() -->
foo
<!-- $('p').append() -->
</p>
index.html(完成)
<!doctype html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
    <title>トップページ</title>
  </head>

  <body>

    <main>
      <p>内容</p>
    </main>

    <script>
      $(function() {
        $.get('header.html', function(data){
          $('body').prepend(data);
        });
        $.get('footer.html', function(data){
          $('body').append(data);
        });
      });
    </script>

  </body>

</html>

iframeを使用する

iframeタグを使用を使用すればHTMLだけで記述を完結させることができます。しかし仕様により表示サイズが決まっており、適切なサイズに変更するにはJavaScriptやCSSを駆使する必要があります。それをやろうとすると前述したJavaScriptの場合よりも難解になるため、この記事では非推奨です。

<iframe src="header.html" frameborder="0"></iframe>
index.html
<!doctype html>
<html lang="ja">

  <head>
    <meta charset="utf-8">
    <title>トップページ</title>
  </head>

  <body>

  <iframe src="header.html" frameborder="0"></iframe>

    <main>
      <p>内容</p>
    </main>

    <iframe src="footer.html" frameborder="0"></iframe> 

  </body>

</html>

どの方法を使えば良いのか?

筆者のおすすめ順は

PHP > SSI > JavaScript/jQuery

であり、PHPかSSIを推奨します。

JavaScript/jQueryはどうしても記述が複雑になり、プログラムの知識も必要なのでハードルが高くなります。iframeは非推奨です。

まとめ

HTMLファイルを部品に切り出して共通化する方法を解説しました。

サイト更新に伴う労力をできるだけ減らし、快適な運営を実現しましょう。

コメント

タイトルとURLをコピーしました