jQuery 1.7的.on()
jQuery 1.7其中一個重點是把Event大改,而新出的.on()除了是效能大增外更是把寫Event Listener的習慣全改了…
Syntax
$("/* event hook element (selector) */")
.on(events // string of event
[, selectors] // *filter* descendant of event hook for triggering:
// * null = trigger on event hook => bind;
// * any selector => delegate
[,data] // `e.data` event data object
, handler // function(e){ /*...*/ }
) //
看上去和傳統的Event hook ( .bind, .live, .delegate ) 分別不大,function signature和.bind()有夠像, 不過根據官方文件這三種都需要轉換, 而原因在經過實戰之後出現了—
因為根本是差很多的東西-至少是selector的組成方面。
Demo
請打開console看output…主要是看bubbling和event object
HTML
簡單的很…
<div class="macro">
<div class="def">
<p class="desc">Click me</p>
</div>
</div>
JS, demystified
影響event listener的作法主要是看event handler的event object,e,及this的定義。
解說都在那句下面的comment內;→是console output ( $(..)[0]是HTMLElement)
$("div.macro div.def").on("click", function(e){
console.log("this",this);
// →$("div.macro div.def")[0], 等同 `e.currentTarget`
//(http://api.jquery.com/event.currentTarget/)
console.log("target",e.target);
// →$("div.macro div.def p.desc")[0],
// 最初發動Event的element (target element initial the bubbling)
console.log("currentTarget",e.currentTarget);
// →$("div.macro div.def")[0]
// Bubble抵達的element (target element within bubbling),
console.log("event",e);
// →經jQeury修改過符合標準的event object
// (http://api.jquery.com/category/events/event-object/)
console.log("real event object", e.originalEvent);
// →瀏覽器產生的原始Event Object, document沒有的屬性都會留在這
//* 所以經jquery.trigger()產生的會是undefined
});
Note
bind? delegate? 看有沒有Filter啦~
預設是不給filter,即是bind-approach (.bind())-Event Hook即觸發事件的Element。(bind-approach)
有給filter會改為用delegate-approach (.delegate()):
- Selector要分拆,因為Event到達上層才會處理。
this會是event hook + filter - e.currentTarget是沒差的。
也就是說listener會大量減少^但handler不用大改。另外新加入的Element不用加listener。(.live()做的事)
bind-approach和delegate-approach的比較在此: bind-approach vs delegate-approach
^也就是說,除非故意event hook掛在document,否則一般情況下不會是live-approach….
Bubbling
因為是依靠bubbling,預設是會一直bubble到document,如果document很深請return一個false或是一接到就叫e.stopPropagation()甚至e.stopImmediatePropagation()去把Event Bubbling停了。
(尤其是你只想該Event由該Element處理時,這樣會減少誤觸)
Extra
如果function是丟named function過去可以用off()去unload,如果只跑一次就unload可以用.one()
Conclusion
.on()好處滿多的,可以的話建議轉換。