end疑問
請教一個問題,關于end(),如果調用遍歷方法,它改變堆棧,我們使用end()方法,ok沒問題,返回上一個堆棧對象,下面這個例子我不是很理解:
<div>測試內容1</div>?
<div>測試內容2</div>?
<script>$('<p>新增內容</p>').appendTo('div').addClass('c1').end().addClass('c2');</script>
為什么end()之后的對象是第二個p?而不是新增的'<p>新增內容</p>',為什么是一個p,不是[p,p]
2015-01-04
感謝版主的回答,特意看了一下appendTo的源碼
jQuery.each({ appendTo:?"append", prependTo:?"prepend", insertBefore:?"before", insertAfter:?"after", replaceAll:?"replaceWith" },?function(?name,?original?)?{ jQuery.fn[?name?]?=?function(?selector?)?{ var?elems, i?=?0, ret?=?[], insert?=?jQuery(?selector?), last?=?insert.length?-?1; for?(?;?i?<=?last;?i++?)?{ elems?=?i?===?last???this?:?this.clone(true); jQuery(?insert[i]?)[?original?](?elems?); //?Modern?browsers?can?apply?jQuery?collections?as?arrays,?but?oldIE?needs?a?.get() core_push.apply(?ret,?elems.get()?); } return?this.pushStack(?ret?); }; });1)insert取得選擇器div的2個對象,然后進行循環
2)第一次循環elems保存this($('<p>新增內容</p>'))的克隆,然后經過jQuery( insert[i] )[ original ]( elems );這里面主要是調用的$(div)的append()方法,而append()方法主要調用js的原生態的appendChild()方法,導致的結果就是,div跟elems有了父子關系,注意這里的elems只是克隆所以不影響this,這時debug可以看到elems是有parentElement的(第一個div);core_push不多說,存放數據組的。
3)第二次循環elems=this,這一句很關鍵,直接跟this綁定,然后elems再執行剛才的第一次Query( insert[i] )[ original ]( elems )這個過程,這時候的insert[i]是第二個div,理所當然的this和elems跟第二個div綁定成了,有了父子關系
4)循環結束進入我們堆棧操作this.pushStack( ret ),里面比較簡單
pushStack:?function(?elems?)?{ //?Build?a?new?jQuery?matched?element?set var?ret?=?jQuery.merge(?this.constructor(),?elems?); //?Add?the?old?object?onto?the?stack?(as?a?reference) ret.prevObject?=?this; ret.context?=?this.context; //?Return?the?newly-formed?element?set return?ret; },返回數組的prevObject設置成第三步的this
2014-12-30
這個問題問的很好,為什么不是數組的[p,p]?
這里我們要從本質上出發,我這個p是怎么來的?
是通過
$('<p>新增內容</p>')產生的,但是這個p元素是不是只有一個?
只是通過appendTo('div')的時候,會產生二個,其實是因為appendTo內部在調用文檔碎片clone了一個p,所以才會存在2個p元素
那么end的本質是調用prevObject的引用,prevObject其實是保存最終引用的
$('<p>新增內容</p>')這個產生的p,所以為什么只有一個的原因了