jquery.jsを読み解くを見て勉強(第3回分)
id:lesamoureuses:20080805:1217957807
id:lesamoureuses:20080809:1218269672
に引き続き第3回分。
jQuery.fn.map
jQuery.mapに自身のjQueryオブジェクトと引数で受け取ってるcallback関数を渡し、
その結果(ただの配列)をスタックに入れてjQueryオブジェクトにして返してる
jQuery.fn.mapとjQuery.mapの違い
例えば、
jQuery('div').map(function (index, domElement) { console.debug(this); // domElementと同じ return domElement; });
は、thisとdomElementは同じものになり、戻り値はjQueryオブジェクト。
一方、
jQuery.map(jQuery('div'), function(domElement, index){ console.debug(this); // window console.debug(domElement); // jQuery.fn.mapのdomElementと同じ return domElement; });
はthisとdomElementは違うものになり、戻り値はただの配列。
jQuery.fn.domManip
jQuery.fn.append,jQuery.fn.prependなどで使われていて、
argsがjQery.fn.appendなどに渡された引数、
callbackがjQery.fn.appendなどの処理本体になってる。
clone = this.length > 1
のthisはjQueryオブジェクト。
対象となる要素が複数あればtrue、1つもしくはナシならばfalseになる
487行目this.eachで対象となる要素全てに処理。
function(){}の中に入って、thisは一つ一つの要素になる。
例えば、
$('p').append('<span>hello</span>', 'world')
だと、$('p')でページ内の<p>を全て保持し、functionの中のthisは
それぞれ。
0489: elems = jQuery.clean( args, this.ownerDocument );
でargsをjQuery.cleanに渡し、パラメータの文字列をDOMにしてelemsに入れる。
さっきの例だと、elemsはとtextNodeの配列になる。
次。table処理。
0497: if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) ) 0498: obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
jQuery.fn.appendやjQuery.fn.prependでtableの中に要素を追加することがあるので、
パラメータのtableがtrueになる。
$('table').append('<tr>row</tr>');
みたいなときにthisは<table>、elems[0]が<tr>なので当てはまる。
502行目。
elemsの要素分だけループ処理。
次の行。
0503: var elem = clone ? 0504: jQuery( this ).clone( true )[0] : 0505: this;
cloneがtrueの時、つまり、
$('p').append('<span>hello</span>', 'world')
としたときに、ページ内に対象となる<p>が一つしかない時は、
パラメータの要素を一度だけ追加すれば良いのでthisで良い。
<p>が複数あった場合はelemsを何度も使いまわすのでcloneを作る。
最後513行目。
0513: scripts = scripts.add( jQuery( "script", elem ).remove() );
jQuery( "script", elem )は$(elem).find("script")と同じ。
パラメータの要素の子要素にscriptがあればそれを取り出し、
remove()でページから削除。
jQuery.extend,jQuery.fn.extend
初めの引数がtrueの場合は階層深くまで上書きをする。
var obj1 = { d1: { d2_1: 'a', d2_2: 'a' } } var obj2 = { d1: { d2_1: 'b' } }
とあった場合、
$.extend(true,obj1,obj2)
だと、
var obj1 = { d1: { d2_1: 'b', d2_2: 'a' } }
となり、
$.extend(obj1,obj2)
だと、
var obj1 = { d1: { d2_1: 'b', } }
という風にd1が階層を考慮されずに上書きされる。
jQuery.isFunction
prototype.jsのようにtypeofでfunctionかどうかを判別しようとすると、
typeof document.createElement('object').getAttribute typeof document.createElement('input').focus
のような例がIEでは「object」と判断されるためダメ。
jQuery.each
object.length == undefined
で、ハッシュの場合と配列の場合の動きを分けてる。
ハッシュはlengthプロパティがないので「var name in object」でループ。
配列はlengthプロパティがあって「var i = 0, length = object.length; i < length; i++」でループ。