jquery.jsを読み解く

第3回 jQueryライブラリ(470行目~769行目)

この記事を読むのに必要な時間:およそ 8 分

今回は,470行目~769行目までを解説します。

slice()

0470:  slice: function() {
0471:    return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
0472:  },
0473:

sliceメソッドは,Arrayオブジェクトのsliceを実行しています。わざわざ別のメソッドを定義しているのは,pushStackを使って現在の状態をスタックに格納するためです。

map()

0474:  map: function( callback ) {
0475:    return this.pushStack( jQuery.map(this, function(elem, i){
0476:      return callback.call( elem, i, elem );
0477:    }));
0478:  },
0479:

mapメソッドは,配列の各要素に関数を適用します。Array.mapはJavaScript 1.6から実装されていますが,1175行目で独自に実装されています。ここでもスタックに格納しています。

andSelf()

0480:  andSelf: function() {
0481:    return this.add( this.prevObject );
0482:  },
0483:  

andSelfメソッドは,直前に選択されていた要素を現在選択されている要素に加えて返します。

domManip()

0484:  domManip: function( args, table, reverse, callback ) {
0485:    var clone = this.length > 1, elems; 
0486:
0487:    return this.each(function(){
0488:      if ( !elems ) {
0489:        elems = jQuery.clean( args, this.ownerDocument );
0490:
0491:        if ( reverse )
0492:          elems.reverse();
0493:      }
0494:
0495:      var obj = this;
0496:
0497:      if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
0498:        obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
0499:
0500:      var scripts = jQuery( [] );
0501:
0502:      jQuery.each(elems, function(){
0503:        var elem = clone ?
0504:          jQuery( this ).clone( true )[0] :
0505:          this;
0506:
0507:        // execute all scripts after the elements have been injected
0508:        if ( jQuery.nodeName( elem, "script" ) ) {
0509:          scripts = scripts.add( elem );
0510:        } else {
0511:          // Remove any inner scripts for later evaluation
0512:          if ( elem.nodeType == 1 )
0513:            scripts = scripts.add( jQuery( "script", elem ).remove() );
0514:
0515:          // Inject the elements into the document
0516:          callback.call( obj, elem );
0517:        }
0518:      });
0519:
0520:      scripts.each( evalScript );
0521:    });
0522:  }
0523:};
0524:

domManipメソッドは,第2回で紹介したappend(),prepend(),before()などのメソッドから利用される内部処理用の関数です。 まず,485行目では,選択されている要素が複数あるかどうかを判定しています。次に489行目で初回ループ時のみcleanメソッドを実行し,argsとして渡された処理対象のエレメントをelems変数に格納します。また,もしreverseが真ならばelemsの各要素を逆順にしておきます。

次に497行目ですが,table要素を操作する際にtbody要素がなければ生成して,obj変数に格納します。これは,Internet ExplorerでtbodyがないとうまくDOM操作が動かないための対処です。

次に500行目からは,要素に対してcallback関数を適用する部分なのですが,script要素が含まれていたら変数に待避しておきます。そして,最後に520行目でまとめてscriptの内容を評価します。

initプロトタイプ定義

0525:// Give the init function the jQuery prototype for later instantiation
0526:jQuery.prototype.init.prototype = jQuery.prototype;
0527:

後にインスタンス化するときのために,jQuery.prototype.initメソッドのプロトタイプにjQueryオブジェクトのプロトタイプを設定しています。これによって,ここまで説明してきたjQuery.prototypeに定義された様々なメソッドやプロパティを継承しています。

evalScript()

0528:function evalScript( i, elem ) {
0529:  if ( elem.src )
0530:    jQuery.ajax({
0531:      url: elem.src,
0532:      async: false,
0533:      dataType: "script"
0534:    });
0535:
0536:  else
0537:    jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
0538:
0539:  if ( elem.parentNode )
0540:    elem.parentNode.removeChild( elem );
0541:}
0542:

528行目は,evalScript関数の定義です。先ほどのdomManipメソッドの中で登場しましたが,DOM操作の際にscriptタグを後から実行するためのものです。529行目でsrc属性が指定されていればajaxメソッドを使って外部スクリプトを読み込み,実行します。そうでなければ,直接スクリプトを評価して実行します。

そして,親要素が存在するときは渡された要素を削除します。

著者プロフィール

山下英孝(やましたひでたか)

大学を卒業後,大手SIerに就職し,電機メーカーの研究所勤務を経て,ウノウに入社。1年半に渡ってWebサイトの開発,ディレクション,運用を経験した後に独立。2008年2月よりフリーエンジニアとして活動中。好きな言語はJavaScriptとPythonで,Linuxサーバ運用管理も得意。

ブログWeboo! Returns.

コメント

コメントの記入