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

Link

請打開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()好處滿多的,可以的話建議轉換。

Tags: jquery event