解説コードを読んでみよう
このサンプルでわかること
- ajax(エイジャックス)で、ページを再読み込みせずにサーバーとやりとりする流れ
- jQuery の
$.ajax()の基本的な書き方 - あとから追加した要素のイベントを受け取る「イベントの委譲」
使っているファイル
- index.phpデモのページ(ボタンと、ajax を送る JavaScript)
- data.phpajax で呼ばれる PHP。番号を受け取り、部品の HTML を返す
ajax の流れ
ふつうのリンクやフォーム送信では、ページ全体が切り替わります。ajax を使うと、ページはそのままで、裏でサーバーとデータをやりとりし、結果だけを画面に反映できます。
| 順番 | どこで | 何をする |
|---|---|---|
| ① | ブラウザ(index.php の JavaScript) | 「部品を追加」が押されたら、num=1 のようなデータを data.php に POST で送る |
| ② | サーバー(data.php) | $_POST['num'] で番号を受け取り、部品の HTML を作って出力(=返事)する |
| ③ | ブラウザ | 返ってきた HTML を .append() で #add の中に追加する |
1. ブラウザ側:ajax でデータを送る
// ① ボタンを押したら data.php に番号を送り、返ってきた HTML を追加する
$('#post').on('click', function(){
num = num + 1;
$.ajax({
url: 'data.php',
type: 'POST',
data: { num: num },
dataType: 'html'
}).done(function(data){
$('#add').append(data);
});
});
| 設定 | 意味 |
|---|---|
url | 送り先のファイル |
type | 送り方。'POST' または 'GET' |
data | 送るデータ。{ 名前: 値 } の形で書く |
dataType | 返ってくるデータの種類(ここでは HTML) |
.done(function(data){ … }) | 返事が届いたときの処理。data に返事の中身が入る |
2. サーバー側:受け取って HTML を返す
data.php は、echo などで出力した内容がそのまま「返事」になります。ここでは受け取った番号を入れた部品の HTML を返しています。
<?php
/*
* ajax で呼ばれるファイル
* 送られてきた番号 num を受け取り、追加する部品(HTML)を返します。
*/
$num = (int)($_POST['num'] ?? 0); // 数字以外が送られても安全なように整数にする
?>
<div class="item" id="item-<?= $num ?>">
<span class="item__no"><?= $num ?>個目</span>
<button type="button" class="btn hello">あいさつ</button>
<button type="button" class="btn del">削除</button>
<span class="item__msg"></span>
</div>
6行目の (int)(…) は「整数に変換する」という意味です。ブラウザから送られてくる値は、悪意のある人が自由に書き換えられます。数字しか来ないはずの値は、受け取った直後に数字に変換しておくと安全です。?? 0 は「値が送られてこなかったら 0 にする」という書き方です。
3. 追加された部品のボタンを動かす(イベントの委譲)
「削除」や「あいさつ」のボタンは、ページを開いたときにはまだ存在しません。そこで、最初からある親の #add にイベントを登録し、「中の button.del がクリックされたら」と対象を指定します。
// ② あとから追加された部品のボタンにも効くよう、親の #add にイベントを登録する
$('#add').on('click', 'button.del', function(){
$(this).closest('.item').remove();
}).on('click', 'button.hello', function(){
$(this).siblings('.item__msg').text('こんにちは!');
});
$('button.del').on('click', …) と書くと、登録した時点で存在するボタンにしか効きません。ajax で後から追加した要素を動かすときは、$(親).on('click', '子のセレクタ', …) の形を使いましょう。
data.php の HTML に「色を変える」ボタンを足し、index.php に .on('click', 'button.color', …) を追加して、部品の背景色を変えてみましょう。