WebNAUT

【javaScript】ajaxがうまくいかない、使い方が分からない…実践的な開発上の2つの注意点【jQuery】

※この記事は2014年12月18日に執筆された記事です。現在は仕様が異なる可能性があります。


ajaxはもちろん知っているけど実はきちんと使ったことが無い…という方もいらっしゃるのではないでしょうか。
ビーワークスのコーポレートサイトで使用しているajaxの実践的なノウハウをご紹介します。


目次


ajaxの基本

ajaxはwebサーバと非同期通信を行い、通信結果を使って行う処理の総称です。
Googleの検索欄に単語を入力すると検索ボタンを押さなくても途中で検索結果が表示されますが、あれはまさにajaxですね。

ビーワークスコーポレートサイトの制作実績ページでもajaxを活用しており、
一定の位置までスクロールした際4件ずつ次の実績を読み込ませています。

ビーワークスコーポレートサイト 制作実績ページ

これによってあたかも初めから全ての実績が表示されているかのようにストレス無く快適に閲覧できます。

jQueryでajaxを行う

jQueryの$.ajaxを使う場合、以下のように通信方法、対象ファイル、成功時・失敗時の処理などを記述します。

//エラー時の処理など含め、引数を細かく指定できる
$.ajax({
    type: 'GET',
    url: '/PATH/TO/TARGET.html',
    dataType: 'html',
    success: function(data) {
        //取得成功したら実行する処理
        console.log("ファイルの取得に成功しました");
    },
    error:function() {
        //取得失敗時に実行する処理
        console.log("何らかの理由で失敗しました");
    }
});

取得対象がjsonファイルの場合、$.getJSONも使用可能です。

//引数はjsonファイルのパス、データを渡すハッシュ、取得成功時のコールバック関数 のみ
$.getJSON("/PATH/TO/JSON.js", null, function(data,status){
    //取得成功したら実行する処理
    for (var i in data){
        console.log("ファイルの取得に成功しました");
        console.log(data[i].KEY);
    }

});

注意点1:通信〜取得完了までのタイムラグ

ここからは実際のソース(一部抜粋・改変)をもとにajaxの注意点についてご説明します。

実績情報を記載したJSONファイルを取得する

制作実績ページでは、まず必要な情報が出力された以下のようなJSONファイルを取得しています。
実際のJSONファイル

var entryIdList = new Array();
var isDataListReady = false;

(function makeIdList(){
    //現在のページのカテゴリーを調べる
    var cat = $("body").data("category");

    $.getJSON("/works/entryData.js", null, function(data,status){
        //JSONファイルの取得に成功したら、記事のIDをカテゴリー別に配列に格納する
        for (var i in data) {
            if(cat == "all"){
                //全ての実績ページ(/works/)の場合 全記事を対象とする
                entryIdList.push(data[i].id);

            } else {

                if(data[i].category == cat || data[i].subcategory == cat){
                    //カテゴリ別の実績ページ(/works/web/など)の場合 該当記事のみ対象とする 
                    entryIdList.push(data[i].id);
                }
            }
        }

        //上記の処理が終わったことを伝える
        isDataListReady = true;
    });

})();

ちなみに即時関数として実行していますが、以下のように普通に呼び出してもこの場合問題ありません。

function makeIdList(){
    //処理
}
makeIdList();

通信取得が完了したかどうか監視し、次の処理を行う

ajaxの場合、処理の開始と通信成功の間にタイムラグがあります。
その間に取得してきたファイルを使った処理を別の関数で行おうとするとエラーが起きますので、
通信が成功した時点でフラグを立て、次の処理はそのフラグを見て開始するようにします。

制作実績ページでは、isDataListReadyという変数を用意し、これがtrueになったかどうかをsetInterVal()で監視しています。

checkIsDataListReady = setInterval(function(){ajaxAtFirstTime()},50);

function ajaxAtFirstTime(){
    //取得したファイルを使って行う処理

    //タイマーを解除
    clearInterval(checkIsDataListReady);    
}

注意点2:複数のファイルの取得完了の順番

複数のファイルを取得する場合には通信開始の順番と取得完了の順番が異なる可能性を考慮しましょう。
A,B,C,Dというhtmlを順番に取得し、成功時のコールバック関数で取得したhtmlをページに追加するとすると、
通信状況によってC,A,B,DA,D,C,Bといった順番に追加されることがあります。

制作実績ページでは記事の順番を制御するため、ajaxのオプションで通信開始の順番を保持し成功時のコールバック関数では保持された順番に従って配列にデータを格納するようにしています。

var entryDataList = new Array();

//1〜4番目の記事を順番に取得開始
for(var i = 0; i 

4件分通信完了したかどうかを確認後、
entryDataListの中身を順番に挿入すれば常に同じ順番で記事が表示されるというわけです。


まとめ

普通のjsのプログラムでは処理中の時間を気にしなくても済むことが多いですが、
ajaxを使う場合は強く意識する必要があります。

表示速度は特にモバイルではユーザビリティの大きな要素になりますので
大きな画像を多用するようなページではぜひajaxを試してみましょう。