初心者編|無料コーディング教材|HTML・CSS・jQueryを実践で学ぶ

jQueryのload()でHTMLを読み込む方法|部分取得・エラー対策を初心者向けに解説

jQuery loadの使い方を示すアイキャッチ

jQueryのload()を使うと、別のHTMLファイルやテキストファイルを取得し、現在のページ内へ表示できます。「共通のお知らせだけを読み込みたい」「HTMLの一部分だけを取り出したい」というときに便利です。

基本形は$('#result').load('parts/news.html');です。ただし、HTMLファイルをダブルクリックしてfile://で開くと、ブラウザのセキュリティ制限で失敗することがあります。ローカルサーバーまたはWebサーバー上で確認してください。

この記事では、読み込み前から完了後までの実例を作りながら、部分取得、完了時の処理、エラー対策、同一オリジン制約、同名のloadイベントとの違いを初心者向けに解説します。

jQueryのload()とは

load()は、サーバーからHTMLなどを取得し、選択した要素の中へ挿入するjQueryのAjax用メソッドです。Ajaxとは、ページ全体を再読み込みせずにブラウザとサーバーがデータをやり取りする仕組みです。

loadメソッドがHTMLを取得・抽出・挿入する流れ
load()はファイルを取得し、必要な部分を抽出して、現在のページへ挿入します。

もっとも簡単な書き方は次のとおりです。#resultに一致する要素がページ内にない場合、リクエスト自体が送信されない点にも注意しましょう。

$('#result').load('parts/news.html');

上のコードが成功すると、parts/news.htmlの内容が#resultの子要素として入ります。元から#result内にあった内容は置き換えられます。

load()の引数

引数役割必須か
url取得するファイルやURLを指定する必須
dataサーバーへ送る値をオブジェクトまたは文字列で指定する省略可
complete通信完了後に実行する関数を指定する省略可

dataをオブジェクトで渡すとPOST、それ以外の基本的な読み込みはGETで送信されます。最初はURLと完了時の関数を使えるようになれば十分です。

別のHTMLからお知らせを読み込む実例

ボタンを押すと、別ファイルにあるお知らせカードだけを読み込む画面を作ります。読み込み前は、内容が入る場所を薄いプレースホルダーで示します。

HTMLを読み込む前のお知らせ表示欄
読み込み前は案内文とプレースホルダーを表示し、ボタンを押せる状態にしています。

ファイル構成を用意する

今回は、次の4ファイルを同じプロジェクト内へ配置します。news.htmlだけはpartsフォルダ内に入れてください。

project/
├── index.html
├── style.css
├── script.js
└── parts/
    └── news.html

パスは「今開いているHTMLファイルから見た場所」です。index.htmlからparts/news.htmlを読むため、先頭にparts/を付けます。

読み込み先をindex.htmlに作る

index.htmlにはボタン、進捗を伝える文章、読み込み結果を入れる#news-resultを用意します。jQuery本体はscript.jsより先に読み込みます。

<!doctype html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>jQuery loadの実例</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <main class="demo">
      <p class="demo__label">jQuery .load()</p>
      <h1>お知らせを必要なときだけ読み込みます</h1>
      <p class="lead">
        別のHTMLファイルから、指定したカードだけを現在のページへ表示します。
      </p>

      <button id="load-button" type="button">お知らせを読み込む</button>
      <p id="load-status" class="status" aria-live="polite">
        ボタンを押すと内容が表示されます。
      </p>
      <div id="news-result" class="result">
        <div class="placeholder" aria-hidden="true">
          <span></span><span></span><span></span>
        </div>
      </div>
    </main>

    <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
    <script src="script.js"></script>
  </body>
</html>

aria-live="polite"を付けた文章は、読み込み中・成功・失敗の状態変化を支援技術へ穏やかに伝えます。見た目だけでなく、通信状況を文章でも示すことが大切です。

読み込まれるnews.htmlを作る

parts/news.htmlには、読み込みたいカードへid="news-card"を付けます。カードの外側にも文章を置き、部分取得で入らないことを確認できるようにします。

<section>
  <p>この文章は読み込みません。</p>

  <article id="news-card" class="news-card">
    <div class="news-card__date" aria-hidden="true">
      <strong>19</strong>
      <span>AUG</span>
    </div>
    <div>
      <p class="news-card__tag">サイトからのお知らせ</p>
      <h2>初心者向けの新しい教材を公開しました</h2>
      <p>
        HTMLとCSSを一緒に書きながら、Webページの基本構造を練習できます。
      </p>
      <a href="#details">教材の内容を見る</a>
    </div>
  </article>
</section>

CSSで読み込み前後の見た目を整える

次のCSSは、実際の表示画像で使用した内容です。is-loadedクラスが付くと、結果欄の破線を実線へ切り替えます。

:root {
  color: #172033;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background: #edf3fb;
}

* {
  box-sizing: border-box;
}

body {
  min-height: 100vh;
  margin: 0;
  padding: 44px 24px;
  display: grid;
  place-items: center;
}

.demo {
  width: min(940px, 100%);
  min-height: 620px;
  padding: 56px;
  border: 1px solid #dce5f2;
  border-radius: 28px;
  background: #fff;
  box-shadow: 0 26px 72px rgb(42 63 104 / 13%);
}

.demo__label {
  margin: 0 0 12px;
  color: #2766d5;
  font-weight: 800;
  letter-spacing: .08em;
}

h1 {
  margin: 0;
  font-size: clamp(32px, 5vw, 48px);
  line-height: 1.3;
}

.lead {
  margin: 18px 0 28px;
  color: #5b677d;
  font-size: 19px;
  line-height: 1.8;
}

button {
  min-height: 52px;
  padding: 13px 24px;
  border: 0;
  border-radius: 12px;
  color: #fff;
  background: #2766d5;
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}

button:focus-visible {
  outline: 4px solid #f5bd42;
  outline-offset: 4px;
}

.status {
  margin: 18px 0 10px;
  color: #536078;
}

.result {
  min-height: 228px;
  padding: 28px;
  border: 2px dashed #cbd7e9;
  border-radius: 20px;
  background: #f8faff;
}

.result.is-loaded {
  border-style: solid;
  border-color: #b8cae9;
  background: #fff;
}

.placeholder {
  display: grid;
  gap: 18px;
  padding: 24px 0;
}

.placeholder span {
  display: block;
  height: 20px;
  border-radius: 999px;
  background: #e1e8f3;
}

.placeholder span:nth-child(1) { width: 38%; }
.placeholder span:nth-child(2) { width: 82%; }
.placeholder span:nth-child(3) { width: 66%; }

.news-card {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: 24px;
  align-items: start;
}

.news-card__date {
  display: grid;
  place-items: center;
  min-height: 96px;
  border-radius: 18px;
  color: #fff;
  background: linear-gradient(145deg, #2766d5, #684fd0);
}

.news-card__date strong {
  font-size: 36px;
  line-height: 1;
}

.news-card__date span {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .14em;
}

.news-card__tag,
.news-card h2,
.news-card p {
  margin: 0;
}

.news-card__tag {
  color: #2766d5;
  font-size: 14px;
  font-weight: 800;
}

.news-card h2 {
  margin-top: 6px;
  font-size: 26px;
}

.news-card p:not(.news-card__tag) {
  margin-top: 10px;
  color: #5b677d;
  line-height: 1.7;
}

.news-card a {
  display: inline-block;
  margin-top: 12px;
  color: #2766d5;
  font-weight: 800;
}

.error-message {
  margin: 48px 0;
  color: #b42318;
  font-weight: 700;
  text-align: center;
}

@media (max-width: 640px) {
  body { padding: 20px; }
  .demo { padding: 32px 24px; }
  .news-card { grid-template-columns: 1fr; }
  .news-card__date { width: 84px; min-height: 84px; }
}

スマートフォン幅ではカードを1列にし、日付と本文が横へはみ出さないようにしています。Tabキーでボタンを選んだときは、黄色いアウトラインが表示されます。

クリック時にHTMLの一部を読み込む

script.jsでは、ボタンのクリック後にparts/news.html#news-cardだけを取得します。URLとセレクタの間には、必ず半角スペースを1つ入れてください。

const $loadButton = $('#load-button');
const $loadStatus = $('#load-status');
const $newsResult = $('#news-result');

$loadButton.on('click', function () {
  $loadButton.prop('disabled', true);
  $loadStatus.text('読み込み中です…');

  $newsResult.load(
    'parts/news.html #news-card',
    function (_responseText, textStatus, jqXHR) {
      if (textStatus === 'error') {
        $newsResult.html(
          `<p class="error-message">読み込めませんでした(HTTP ${jqXHR.status})</p>`
        );
        $loadStatus.text(
          '通信に失敗しました。時間をおいてもう一度お試しください。'
        );
        $loadButton.prop('disabled', false);
        return;
      }

      $newsResult.addClass('is-loaded');
      $loadStatus.text('お知らせを読み込みました。');
      $loadButton.text('読み込み済み');
    }
  );
});

prop('disabled', true)は、通信中の連打を防ぎます。完了時の関数ではtextStatusを確認し、失敗した場合だけエラー表示へ切り替えています。

別HTMLからお知らせカードだけを読み込んだ画面
成功すると、parts/news.html内の#news-cardだけが結果欄へ表示されます。

表示画像は、掲載コードをローカルHTTPサーバー上で実行した結果です。news.htmlの「この文章は読み込みません。」は画面へ入らず、指定したカードだけが表示されています。

HTMLの一部だけを読み込む書き方

部分取得では、load()の第1引数に「URL、半角スペース、セレクタ」をまとめて指定します。セレクタとは、HTML要素を探すための#id.classなどの記述です。

// idがnews-cardの要素だけを読み込む
$('#result').load('parts/news.html #news-card');

// classがnews-itemの要素をすべて読み込む
$('#result').load('parts/news.html .news-item');

次のように第2引数へセレクタを書くと、部分取得にはなりません。第2引数はサーバーへ送るデータとして扱われるためです。

// 間違い:第2引数は抽出用セレクタではありません
$('#result').load('parts/news.html', '#news-card');

半角スペースがない'parts/news.html#news-card'も別のURLとして扱われます。ファイル名とセレクタの間をよく確認してください。

テキストファイルを読み込む方法

HTMLだけでなく、同じサーバー上のテキストファイルも読み込めます。まずmessage.txtへ表示したい文章を書きます。

メンテナンスは終了しました。ご協力ありがとうございました。

読み込み先のHTMLとJavaScriptは次のとおりです。

<p id="message">お知らせを読み込み中です。</p>
$('#message').load('message.txt');

成功すると、#message内の「お知らせを読み込み中です。」が、テキストファイルの文章へ置き換わります。改行や装飾を細かく制御したい場合は、HTMLファイルを使うほうが分かりやすいです。

完了時のコールバックで成功と失敗を確認する

load()の最後に関数を渡すと、通信が完了したあとに処理を実行できます。この関数をコールバック関数と呼びます。

$('#result').load(
  'parts/news.html',
  function (responseText, textStatus, jqXHR) {
    if (textStatus === 'error') {
      console.error('読み込み失敗:', jqXHR.status, jqXHR.statusText);
      return;
    }

    console.log('読み込み成功');
  }
);
引数確認できる内容
responseTextサーバーから返った本文
textStatussuccessnotmodifiederrorなどの状態
jqXHRHTTPステータスやレスポンス情報を持つオブジェクト

404ならファイルの場所、403ならアクセス権限、500ならサーバー側の処理を確認するなど、HTTPステータスから原因を絞り込めます。利用者向けの画面には専門的なエラー全文を出さず、再試行方法を短く案内しましょう。

load()が動かないときの確認項目

HTMLをfile://で開いている

ファイルをダブルクリックして開くと、アドレスがfile:///...になります。ブラウザはローカルファイルを安全のため別々の不透明なオリジンとして扱うことがあり、同じフォルダでもAjaxが失敗します。

VS CodeのLive Serverなどを使い、http://localhost:...で開いてください。本記事の表示画像もローカルHTTPサーバー上で確認しています。

別ドメインのHTMLを読み込んでいる

Ajaxリクエストは同一オリジンポリシーの対象です。URLのプロトコル、ホスト、ポートのどれかが違うと別オリジンになり、相手のサーバーがCORSを許可していなければ読み込めません。

自分で管理していない外部サイトのHTMLを、そのままload()で取得することはできないと考えてください。自サイトの同じオリジンにあるファイルを基本にします。

パスや大文字・小文字が違っている

parts/news.htmlparts/News.htmlは、サーバーによって別ファイルとして扱われます。開発者ツールのNetworkタブでリクエストURLとHTTPステータスを確認しましょう。

jQueryの読み込み順が逆になっている

$ is not definedと表示された場合は、jQuery本体が読み込まれていません。jQueryのscriptタグを、自分のscript.jsより前に置きます。

指定したセレクタが取得先に存在しない

通信が成功しても、#news-cardが取得先のHTMLに存在しなければ結果は空になります。IDの重複、ピリオドとシャープの違い、スペルを確認してください。

load()とloadイベントを混同しない

jQueryには、名前が似た2種類のload処理がありました。HTMLを取得するAjaxの.load(url)は利用できます。一方、画像などの読み込み完了を監視する古いイベント省略形.load(handler)は非推奨になったあと、jQuery 3.0で削除されています。

// HTMLを取得するAjaxメソッド:利用できます
$('#result').load('parts/news.html');

// 古いイベント省略形:使用しません
$('#hero-image').load(function () {
  console.log('画像の読み込み完了');
});

// loadイベントはon()で設定します
$('#hero-image').on('load', function () {
  console.log('画像の読み込み完了');
});

「loadは非推奨」という説明を見たときは、URLを渡すAjaxメソッドの話か、関数を渡すイベント省略形の話かを確認してください。

POSTで値を送りながら読み込む

第2引数へオブジェクトを渡すと、jQueryはPOSTリクエストを送ります。次の例は検索語をsearch.phpへ送り、返されたHTMLを表示します。

$('#search-result').load(
  'search.php',
  { keyword: 'jQuery' },
  function (_responseText, textStatus) {
    if (textStatus === 'error') {
      $('#search-result').text('検索結果を取得できませんでした。');
    }
  }
);

サーバー側には、受け取った値の検証やエスケープが必要です。検索、認証、データ更新など処理が複雑になる場合は、$.ajax()fetch()を使うと設定を明示しやすくなります。

読み込むHTMLとJavaScriptの注意点

URLだけを指定した場合、取得したHTMLはhtml()で挿入され、含まれるscriptが実行されたあとに取り除かれることがあります。URLの後ろへセレクタを付けた部分取得では、scriptは挿入前に取り除かれ、実行されません。

読み込むHTML内のscriptへ依存せず、必要なJavaScriptは現在のページ側で明示的に読み込んでください。また、load()はHTMLをページへ挿入するため、信頼できない利用者入力や外部HTMLをそのまま読み込むとクロスサイトスクリプティングの原因になります。

WordPressで共通部分を読み込む場合

WordPressのヘッダー、フッター、サイドバーなど、ページ表示時から必要な共通部分をload()で後付けする必要はありません。テーマのテンプレートパーツやブロックパターンを使うほうが、検索エンジンやJavaScriptを使えない環境にも最初から内容を届けられます。

load()は、ボタン操作後に補足を開くなど、ページ表示後に必要になる小さなHTML断片へ使います。目的に応じてサーバー側のテンプレートと使い分けましょう。

よくある質問

load()でJSONも読み込めますか?

load()は、取得した内容をHTMLとして要素へ入れる用途に向いています。JSONを受け取り、値ごとに処理したい場合は$.getJSON()$.ajax()、またはfetch()を使ってください。

読み込み後の要素へクリックイベントを付けられますか?

付けられます。完了コールバック内で設定するか、最初から存在する親要素へイベントを委譲します。同じHTMLを何度も読み込む場合は、イベントが重複しない委譲が扱いやすいです。

$('#news-result').on('click', '.news-card a', function (event) {
  event.preventDefault();
  console.log('読み込み後のリンクが押されました');
});

取得したHTMLは検索エンジンに読まれますか?

JavaScript実行後の内容を処理できる検索エンジンもありますが、確実とは限りません。記事本文や商品情報など、検索やページ理解に欠かせない内容は最初のHTMLへ含め、操作後の補助表示にload()を使ってください。

まとめ

  • $('#result').load('parts/news.html')で別HTMLを要素内へ読み込める
  • 部分取得は「URL、半角スペース、セレクタ」を第1引数へまとめる
  • 完了コールバックで成功・失敗を確認し、利用者へ状態を伝える
  • file://ではなくローカルHTTPサーバーで動作確認する
  • 別オリジンの読み込みはCORSの許可が必要
  • 非推奨・削除済みなのはイベント省略形の.load(handler)で、Ajaxの.load(url)とは別物

まずは掲載した4ファイルを同じ構成で用意し、ローカルサーバーで開いてみてください。読み込み前の案内、カードの表示、存在しないパスに変えたときのエラーの3つを確認すると、load()の流れをつかみやすくなります。