jquery.jsを読み解く

第11回jQueryライブラリ(2365行目~2529行目)

今回は、Ajax関連の処理を取り扱う部分の解説になります。

IEメモリリーク対策

2365: // Prevent memory leaks in IE
2366: // And prevent errors on refresh with events like mouseover in other browsers
2367: // Window isn't included so as not to unbind existing unload events
2368: jQuery(window).bind("unload", function() {
2369:   jQuery("*").add(document).unbind();
2370: });

2368行目から2370行目は、Internet Explorerのメモリリーク対策のための処理です。window.unloadイベント発生時に、イベントを一括解除します。既に存在するunloadイベントを解除してしまわないようにwindowオブジェクトは含めません。

jQuery.fn.load()

2371行目からは、外部からHTMLの断片を読み込み表示するload()メソッドの定義部分になります。

2371: jQuery.fn.extend({
2372:   load: function( url, params, callback ) {
2373:     if ( jQuery.isFunction( url ) )
2374:       return this.bind("load", url);
2375: 
2376:     var off = url.indexOf(" ");
2377:     if ( off >= 0 ) {
2378:       var selector = url.slice(off, url.length);
2379:       url = url.slice(0, off);
2380:     }
2381: 
2382:     callback = callback || function(){};
2383: 

2372行目にあるように引数として、url、外部サーバに渡すparams、そしてコールバック関数callbackが渡されてきます。次に2373行目ですが、もし引数urlが関数オブジェクトであれば、現在要素のonloadイベントに割り当てます。これは、load(fucntion(){..})の書式で、このイベント定義もここで行っていることが分かります。

2376行目から2380行目は、urlの後にセレクタ式が続く場合の処理で、この場合はスペースまでをurl変数、スペース以降をselector変数に格納します。

2382行目、callback変数が定義されていなければ、何もしないダミー関数を設定します。

2384:     // Default to a GET request
2385:     var type = "GET";
2386: 
2387:     // If the second parameter was provided
2388:     if ( params )
2389:       // If it's a function
2390:       if ( jQuery.isFunction( params ) ) {
2391:         // We assume that it's the callback
2392:         callback = params;
2393:         params = null;
2394: 
2395:       // Otherwise, build a param string
2396:       } else {
2397:         params = jQuery.param( params );
2398:         type = "POST";
2399:       }
2400: 

外部サーバに対するリクエストメソッドのデフォルトは、2385行目にあるように"GET"です。

2388行目以降は、第2引数paramsが設定されていて、それが関数であればcallback関数に割り当てます。そうでなければ、2836行目で定義されているjQuery.param()メソッドを使ってクエリーパラメータを組み立てます。また、リクエストメソッドを"POST"に設定します。

2401:     var self = this;
2402: 

2401行目は、self変数に自身を設定しています。

2403:     // Request the remote document
2404:     jQuery.ajax({
2405:       url: url,
2406:       type: type,
2407:       dataType: "html",
2408:       data: params,
2409:       complete: function(res, status){
2410:         // If successful, inject the HTML into all the matched elements
2411:         if ( status == "success" || status == "notmodified" )
2412:           // See if a selector was specified
2413:           self.html( selector ?
2414:             // Create a dummy div to hold the results
2415:             jQuery("<div/>")
2416:               // inject the contents of the document in, removing the scripts
2417:               // to avoid any 'Permission Denied' errors in IE
2418:               .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
2419: 
2420:               // Locate the specified elements
2421:               .find(selector) :
2422: 
2423:             // If not, just inject the full result
2424:             res.responseText );
2425: 
2426:         self.each( callback, [res.responseText, status, res] );
2427:       }
2428:     });
2429:     return this;
2430:   },
2431: 

2404行目からは、jQuery.ajax()メソッドを使って、実際のリクエストを行う部分になります。引数として、先ほど設定したurl,type,paramsを利用します。また2409行目以降で、Ajaxリクエストが完了した場合の処理を定義しています。2411行目、もしstatusが"success"もしくは"notmodified"ならば取得した結果を挿入します。ここで、取得した結果から絞り込みを行うためのselectorが指定されている場合は、ダミーの<div />要素を作成して一旦その中に挿入してからfilter()メソッドを適用します。ただし、Internet Explorerで発生する"Permission Denied"エラーを抑制するために予めscriptタグは除去しておきます。

最後に2426行目でcallback関数を呼び出して、戻り値として自身を返して終了です。

jQuery.fn.serialize()

2432:   serialize: function() {
2433:     return jQuery.param(this.serializeArray());
2434:   },

2432行目からは、Formの値をシリアライズするjQuery.fn.serialize()メソッドの定義です。serializeArray()メソッドを呼び出して、その結果をjQuery.param()メソッドを使って、key=value形式に変換して返します。

jQuery.fn.serializeArray()

2435:   serializeArray: function() {
2436:     return this.map(function(){
2437:       return jQuery.nodeName(this, "form") ?
2438:         jQuery.makeArray(this.elements) : this;
2439:     })
2440:     .filter(function(){
2441:       return this.name && !this.disabled && 
2442:         (this.checked || /select|textarea/i.test(this.nodeName) || 
2443:           /text|hidden|password/i.test(this.type));
2444:     })
2445:     .map(function(i, elem){
2446:       var val = jQuery(this).val();
2447:       return val == null ? null :
2448:         val.constructor == Array ?
2449:           jQuery.map( val, function(val, i){
2450:             return {name: elem.name, value: val};
2451:           }) :
2452:           {name: elem.name, value: val};
2453:     }).get();
2454:   }
2455: });
2456: 

2435行目からは、jQuery.fn.serializeArray()の処理になります。先ほどのserialize()メソッドとの違いは、戻り値がJSON形式で返ってくる点です。内部処理はjQueryメソッドのチェーンになっています。

2436行目のmapメソッドで選択要素のnodeNameを調べ、formであればその要素を返し、そうでなければ自身を返します。

2440行目のfilterメソッドによって、name属性が設定されていて、disableではないものでかつ、checked属性があるか、select要素またはtextarea要素か、もしくはtypeがtext,hidden,passwordであるものを抽出します。

2445行目のmapメソッドで、value値を取り出します。そして、2447行目でその値がnullでなくて、Array型であればmapメソッドによってさらに内部の配列要素を取り出します。

最後に、2453行目のget()メソッドによってjQuery.makeArrayメソッドを使ってクリーンにした配列を返します。

AJAX関連のイベント割り当て

2457: // Attach a bunch of functions for handling common AJAX events
2458: jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
2459:   jQuery.fn[o] = function(f){
2460:     return this.bind(o, f);
2461:   };
2462: });
2463: 

2458行目からは、Ajax関連イベントの割り当て処理になります。ajaxStart,ajaxStop,ajaxComplete..などのイベントを現在選択中の要素に割り当てます。ここで面白いのは、これらの関数はどこにも定義されていなくて、ライブラリの利用者が定義したものをそのまま実行する形になります。

jQuery.get()

2464: var jsc = (new Date).getTime();
2465: 
2466: jQuery.extend({
2467:   get: function( url, data, callback, type ) {
2468:     // shift arguments if data argument was ommited
2469:     if ( jQuery.isFunction( data ) ) {
2470:       callback = data;
2471:       data = null;
2472:     }
2473:     
2474:     return jQuery.ajax({
2475:       type: "GET",
2476:       url: url,
2477:       data: data,
2478:       success: callback,
2479:       dataType: type
2480:     });
2481:   },
2482: 

2464行目は、ブラウザのキャッシュを回避するためのパラメータを生成して、jsc変数に格納しています。

2466行目からは、簡単にGETリクエストを行うことができるjQuery.get()メソッドの定義です。2469行目で、第2引数に関数が渡された場合は、dataが省略されているものとみなしてcallback変数およびdata変数の値を設定し直します。2474行目を見ると、jQuery.get()メソッドはjQuery.ajax()の単なるラッパであることが分かります。実際のリクエストはjQuery.ajax()によって行われます。

jQuery.getScript()

2483:   getScript: function( url, callback ) {
2484:     return jQuery.get(url, null, callback, "script");
2485:   },
2486: 

2483行目は、外部からJavaScriptファイルを読み込むjQuery.getScript()メソッドの定義になります。こちらは、jQuery.get()の第4引数typeが"script"になっただけで処理内容は同じです。

jQuery.getJSON()

2487:   getJSON: function( url, data, callback ) {
2488:     return jQuery.get(url, data, callback, "json");
2489:   },
2490: 

2487行目は、外部からJSON形式のデータを読み込むjQuery.getJSON()メソッドの定義になります。こちらも、jQuery.get()の第4引数typeが"json"になっただけで処理内容は同じです。

jQuery.post()

2491:   post: function( url, data, callback, type ) {
2492:     if ( jQuery.isFunction( data ) ) {
2493:       callback = data;
2494:       data = {};
2495:     }
2496: 
2497:     return jQuery.ajax({
2498:       type: "POST",
2499:       url: url,
2500:       data: data,
2501:       success: callback,
2502:       dataType: type
2503:     });
2504:   },
2505: 

2491行目は、POSTメソッドを使って外部サーバからコンテンツを取得するjQuery.post()メソッドの定義になります。jquery.get()と同様にjQuery.ajax()メソッドのラッパになっています。違うのは、引数typeが"POST"になっていることで、それ以外の処理は共通になります。

jQuery.ajaxSetup()

2506:   ajaxSetup: function( settings ) {
2507:     jQuery.extend( jQuery.ajaxSettings, settings );
2508:   },
2509: 

2506行目からは、jQuery.ajaxSetup()メソッドの定義です。jQuery.ajax()メソッドを呼び出す際のデフォルト値を設定するためのものです。2507行目のjQuery.extend()メソッドを利用して、次に出てくるajaxSettingsの値を引数settingsで上書きします。

jQuery.ajaxSettings

2510:   ajaxSettings: {
2511:     global: true,
2512:     type: "GET",
2513:     timeout: 0,
2514:     contentType: "application/x-www-form-urlencoded",
2515:     processData: true,
2516:     async: true,
2517:     data: null,
2518:     username: null,
2519:     password: null,
2520:     accepts: {
2521:       xml: "application/xml, text/xml",
2522:       html: "text/html",
2523:       script: "text/javascript, application/javascript",
2524:       json: "application/json, text/javascript",
2525:       text: "text/plain",
2526:       _default: "*/*"
2527:     }
2528:   },
2529:   

2510行目からは、jQuery.ajaxSettingsの定義になります。jQuery.ajax()メソッドによって利用される各種設定のデフォルト値を定義しています。

globalajaxStartやajaxStopといったグローバルイベントを実行するかどうかのフラグでデフォルトはtrue
typeリクエストメソッドの種類
timeout名前のとおり、リクエストのタイムアウト値
contentTypeサーバにデータを送る際のcontent-typeの種類で、デフォルトは"application/x-www-form-urlencoded"。これを変更することはあまりないでしょう
processDatadataに文字列以外のオブジェクトが渡されてきた場合に、クエリー文字列形式に変換するかどうかのフラグ。デフォルト値はtrueで、DOMなどのデータを送信したい場合はこれをfalseにすると良いでしょう
async非同期通信を行うかどうかのフラグで、falseにすると通信を行っている間の処理はブロックされる
data相手のサーバに送信されるパラメータで、デフォルトはnull
username認証が必要な場合に利用されるユーザID
password認証が必要な場合に利用されるパスワード
acceptsサーバに送信されるAcceptヘッダの種類

おすすめ記事

記事・ニュース一覧