SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

JavaScriptとPHPでつくるAjaxインクリメンタル検索

Ajaxとデータベースアプリケーション作成の基本

  • X ポスト
  • このエントリーをはてなブックマークに追加

JavaScriptでインクリメンタル検索を実装する

 いよいよ本題の(?)、Ajaxインクリメンタル検索の作成を行います。

 余談ですが、仕様化はフロント側(画面など)から行いますが、実装はバック側(テーブル実装など)から行うのが一般的です。Ajaxを使いこなす上でも、バック側の実装スキルが必要なのはいうまでもありません。

 早速、JavaScriptによるソースコードを説明します。

XMLHttpRequestを生成する

 XMLHttpRequestは、ブラウザに実装された、HTTPクライアント機能を実現するオブジェクトです。JavaScriptから、フォームを利用したHTTP通信でおなじみの、GETPOSTメソッドを実行し、そのレスポンスを受け取ることができます。これにより、ブラウザのリロード無しでサーバー側とデータ交換できることが、Ajaxのメリットの1つとなっています。

XMLHttpRequestを生成するcreateXmlHttpRequest関数
function createXmlHttpRequest() {
  if (window.XMLHttpRequest) {             // Firefox,Opera,Safari,IE7
    return new XMLHttpRequest();
  } else if (window.ActiveXObject) {                 // IE6
    try {
      return new ActiveXObject("Msxml2.XMLHTTP");    // MSXML3
    } catch(e) {
      return new ActiveXObject("Microsoft.XMLHTTP"); // MSXML2まで
    }
  } else {
    return null;
  }
}
var xmlhttp = createXmlHttpRequest();

 このように、XMLHttpRequestオブジェクトの生成にはブラウザの差異を意識する必要があります。

XMLHttpRequestを利用して検索結果を取得する関数を作る

XMLHttpRequestを利用して検索結果を取得する
/* 抜粋 */
function query() {
   //XMLHttpRequestを生成する
  var xmlhttp = createXmlHttpRequest();        
  //キーワード欄への入力内容
  var q = document.getElementById('q').value;  
  var keyword = encodeURI(q); //URIエンコード

  xmlhttp.open("GET", "search-ajax.php?q=" + keyword, true);
  xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
      //結果をdivの内容として書き換える
      document.getElementById("result").innerHTML 
        = xmlhttp.responseText;
    }
  }
  xmlhttp.send(null)
}

 このコードについて解説します。

  1. xmlhttp.onreadystatechange = function() {
    • XMLHttpRequestオブジェクトの状態が変化する度に呼び出されるイベントハンドラです。ここにイベント発生時の処理を記述します。
  1. if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
    • readyStateは通信の状態を示します。
      • 0 : uninitialized(初期状態)
      • 1 : loading(読み込み中)
      • 2 : loaded(読み込み完了)
      • 3 : interactive(読み込んだデータ解析中)
      • 4 : complete(全て完了(完了または失敗))
    • statusはHTTPのステータスです。一例として、200は正常、404はNotFoundとなります。
  1. document.getElementById("result").innerHTML = xmlhttp.responseText;
    • responseTextはサーバからのレスポンスをそのまま受け取るプロパティです。ここでは検索処理(search-ajax.php)がレスポンスしたHTMLを受け取ることができます。

ユーザのイベントを処理する

 ページが読み込まれた後に、ユーザイベントの監視を開始します。

XMLHttpRequestを利用して検索結果を取得する
window.onload = function() {
  var q = document.getElementById("q");
  if (q.addEventListener) {
    q.addEventListener("keyup", query, false) //Firefox, Opera, Safari
  } else {
    q.attachEvent("onkeyup", query); //IE
  }
  setInterval("query()", 700); 
}
  1. addEventListenerまたはattachEvent
    • 要素に対するイベントを割り当てます。ここでは検索テキストボックスのonkeyupイベント発生時、query関数を呼び出すように指定しています。
  1. setInterval
    • 指定した時間毎に繰り返し処理をするタイマーを設定します。ここでは700ミリ秒ごとにquery関数を呼び出すように指定しています。

状態に応じて検索処理の続行/中断を判断する

 イベントは、サーバと通信中の場合にも発生する可能性があります。また、複数の文字で構成されるキーワードについては、全ての文字が入力されるのを待ってからサーバに問い合わせた方が、サーバの負荷軽減になります。

 というわけで、先ほどのquery関数を書き換えてみます。

query関数で状態に応じた検索処理
var keyword_save = "~^|"; //dummy
var xmlhttp = null;
var baseTime = new Date();
var c = 0;
function query(flg) {
  //キーワード欄への入力内容
  var q = document.getElementById('q').value; 

  //URIエンコード
  var keyword = encodeURI(q);                 

  //前回入力時刻との差(ミリ秒)
  var elapsed = parseInt((new Date()).getTime() - baseTime.getTime());  
  //基準時間の更新
  baseTime = new Date(); 
  //600ミリ秒内に次の文字が入力された場合は
  //キーワード入力中とみなして中断する
  if (elapsed < 600) { 
    return; 
  } 
  //XMLHttpRequestを生成する
  if (!xmlhttp) xmlhttp = createXmlHttpRequest(); 
  if (!xmlhttp || xmlhttp.readyState == 1 
               || xmlhttp.readyState == 2 
               || xmlhttp.readyState == 3) {
    return; 
  }

  if (keyword_save != keyword) {
    xmlhttp.open("GET", "search-ajax.php?q=" + keyword, true);
    xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        document.getElementById("result").innerHTML 
          = xmlhttp.responseText;
      }
    }
    xmlhttp.send(null)
    keyword_save = keyword; //キーワード保存
  }
}

最後に

 全てのサンプルはこちらからダウンロードして下さい。

 Ajaxアプリケーションの基本的な流れを把握できたでしょうか?JavaScriptフレームワークを利用すれば、もっと少ないコードで実装することができるようになります。また、サーバサイドはPHPに限らず、JavaやRubyで構築しても構いません。

 Ajaxはこのほかにも、見栄えを良くしたり、外部のサービスを利用することができたり、非常に強い力を発揮します。これらは、ユーザが対象のアプリケーションをより使いやすくするために用いるべきです。

 「Ajaxが実装できない」のは良くありませんが、システムが複雑になる傾向にあるため、濫用も良くないと考えています。

 読者の皆様が、この記事を通じて積極的に、そしてユーザのためにAjaxを駆使していただければ幸いです。

参考資料

  • Ajaxイン・アクション』(Dave Crane 著、Eric Pascarello 著、Darren James 著、柏原 正三 著、株式会社はてな 著、網代 淳 著、星 睦 著、インプレス、2006年6月)

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

我妻 隆志(ワガツマ タカシ)

宮城県仙台市在住トライポッドワークス株式会社(本社:仙台市)に所属。JavaやPHP、データベースを利用したアプリケーション開発技術を生かし、製品開発・サポート業務に従事。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/2305 2010/11/01 16:26

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング