[jQuery+PHP] Ajax で連動プルダウンを作る方法と高速化
プルダウン A で選択された値を元にサーバーで検索した結果を、プルダウン B の選択肢( option
タグ)に追加し連動するプルダウンを作る。プルダウン A で選択された値は Ajax で PHP に送り、 PHP 側で DB 検索した結果を返し、 jQuery で option
タグに追加していく。
このとき option
タグ生成の速い方法を調べた。
Contents
連動プルダウンを作る方法
サンプルコード。
画面( HTML + PHP )
<label for="aaa">プルダウン A : </label>
<select name="a" id="aaa">
<option selected disabled>未選択</option>
<?php
$res = $mysqli->query("SELECT id, name FROM test");
while( $data = $res->fetch_assoc() ) { ?>
<option value="<?=$data['id']?>"><?=$data['name']?></option>
<?php } ?>
</select>
<label for="bbb">プルダウン B : </label>
<select name="b" id="bbb">
</select>
jQuery
$("#aaa").on('change', function(){
var aVal = $(this).val();
$.ajax({
type: "POST",
url: "hoge.php",
data: { "aaa" : aVal },
dataType : "json"
}).done(function(data){
// map で option タグのオブジェクトを生成しておいて、ループの外で append する
var arr = $.map(data, function (val, index) {
$option = $('
hoge.php ( Ajax から呼ばれて DB 検索する)
$aaa = filter_input(INPUT_POST, "aaa");
// DB から検索する処理
$stmt=$mysqli->prepare("SELECT id, bbb FROM tableb WHERE aaa = ?");
$stmt->bind_param(str_repeat('s', $aaa);
$stmt->execute();
$res = $stmt->get_result();
$list = array();
while( $data = $res->fetch_assoc() ) {
$list[$data['id']] = $data['bbb'];
}
header('Content-Type: application/json');
echo json_encode($list);
option
タグ生成の方法と速度
高速化について調べたところ以下の情報を見つけた。
- DOM へのアクセスは、
id
指定が速い - ループは
for...in
が遅い。(for
が最速らしい) - DOM へのアクセス回数は少ない方がいい → この場合
$.map
でoption
タグの配列を作って、ループの外でappend
するのがいいらしい
以上を踏まえて 3 つの方法の速度を測ってみた。
方法 1 $.each
$.each(data, function(index, val) {
$('#bbb').append($('
方法 2 $.map
var arr = $.map(data, function (val, index) {
$option = $('
方法 3 for...in
for (var key in data){
$('#bbb').append($('
速度測定
それぞれを関数にしてひとつづつ、 console.time()
で計測した。
- PC : Mac
- OS : Amazon Linux
- ブラウザ : Chrome
var array = {'a1':'あいうえお', 'a2':'かきくけこ', 'a3':'さしすせそ', 'a4':'たちつてと', 'a5':'なにぬねの', 'a6':'はひふへほ', 'a7':'まみむめも', 'a8':'やゆよ', 'a9':'アイウエオ', 'a10':'0123456789'};
console.time("time");
test1(array);
console.timeEnd("time");
function test1(data) {
$.each(data, function(index, val) {
$('#bbb').append($('
5 回実行してみた。
test1 (方法 1 $.each )
time: 3.743896484375ms time: 2.001953125ms time: 1.803955078125ms time: 2.02197265625ms time: 0.89306640625ms
test2 (方法 2 $.map )
time: 3.8740234375ms time: 1.425048828125ms time: 0.498046875ms time: 1.10302734375ms time: 0.572021484375ms
test3 (方法 3 for…in )
time: 3.84814453125ms time: 1.64404296875ms time: 1.942138671875ms time: 2.273193359375ms time: 1.72705078125ms
結果
$.map
が速そう。
5 回分の計測結果だけど、何度もやってみるとあまり変わらなかった。件数が多いともっと変わってくるのかもしれないけど。