AJAX通信とUI更新

ここまででかんたんなUIの実装の方法を見てきました。とあるHTMLに対して関連するJS + CSSを定義する。というやり方を紹介してきましたが、実際のWebサイトでは、より複雑な動きを持っている事が多いです。例えば・・

  • 配送画面で郵便番号を入力すると、関連する住所を自動で入力(補完)する。

  • ECサイトの商品一覧画面で絞り込み条件を買えると、商品が絞り込まれる。

こういった動きを実現するために良く使われるのがAjaxと呼ばれる技術です。実際にどんなコードか見ていきましょう。

このサンプルでは、Searchボタンを押すと、上部のテキスト欄に入力された値を元に、検索を行います。(TV MAZEという海外のTV番組の検索サイトの無料のAPIを利用) 例えば Batman で検索すると Batman と関連するサイトが一覧表示されます。同様に Spider man などでも結果が出てくるかと思います。

細かい実装はCodePenのそれぞれのタブ(以下のボタンの部分)を押してみると見られるので、ご興味のある方は見てみてください。

今回はJSのAjaxの部分にフォーカスしてお話したいと思います。

// 検索ボタンがクリックされたら
$("#btn-search").on("click", (e) => {
// #search(= input要素)の値を取得する。
const value = $("#search").val();
// AJAXを使って、指定のURLにリクエストを送る。
$.ajax({
url: "https://api.tvmaze.com/search/shows",
data: {
// このAPIでは "q=検索文字列" としてパラメータを渡すと検索結果が絞り込まれる。
q: value
}
}).then((result) => {
// 検索結果を取得したら、HTMLとして整形する。
const listHtml = result
.map((row) => {
const show = row.show;
/* CSSを適用する事で、左に画像。右にTV番組のタイトル・説明が並ぶレイアウトになる。 */
return `
<div class="row">
<img src="${show.image.medium}">
<div>
<h4>${show.name}</h4>
<div class="summary">${show.summary}</div>
</div>
</div>
`;
})
.join("");
// #shows(div)要素の中身を生成したHTMLで更新する。
$("#shows").html(`<div>${listHtml}</div>`);
});
});

この $.ajax というものが今回の要点です。これはjQueryが用意しているAJAX通信を簡単に行うための関数となります。ブラウザの標準APIでは fetchXMLHttpRequest(古いブラウザ向け) というAPIを使って実現できます。 $.ajax は以下の引数を受け取ります。

  • url = AJAXリクエストを送信する先のAPIサーバのURL

  • data = リクエストに付与するデータ。GETリクエストの場合はURLにクエリ文字列として付与され、POSTリクエストの場合はリクエストボディに付与される。

今回のTV MAZEのAPIでは q="検索文字列" を渡すことで検索を行えるので、テキスト欄に入力された値を q に渡す事で、検索を行っています。

$.ajax は戻り値として Promise を返却します。Promiseは then() というメソッドを呼ぶことで、結果を取得出来ます。 then() の中では第一引数に検索結果(の配列)が渡されるため、後は以前のTab(タブ)のサンプルのように、HTMLを組み立てて $("#shows").html("HTML文字列") とすることで、画面に検索結果を表示しています。

"result .map((row) => {})" という書き方をしていますが、このmap関数というのは呼び出し元の配列の1行ずつを関数の第一引数として渡して実行し、得られた戻り値で作られる別の配列を返却する。という関数です。

例えば "[1,2,3].map((i) => i + 1)" を実行すると "[2, 3, 4]" という結果(それぞれの値に1を足したもの)が得られます。

これ以外にもJavaScriptの配列(Array)にはfilter, reduceといった便利なメソッドが用意されています。活用してみましょう!

このようにAJAX通信を使う事で、従来はブラウザのリロードを伴う遷移(リンクをクリック、フォームを送信する)でしか実現できなかった操作を非同期で(画面をリロードせずに)行うことが出来るようになります。利用者(ユーザ)にとっても使い勝手の良いUIを作る事が出来るので、試してみましょう。