2014年10月15日 星期三

JQuery 的 on() 原理


在JavaScript中,大多數事件會在DOM裡往上一層一層的泡浮,也就是說,當一個元素觸發一個事件時,她會在DOM一直往上泡浮到 document 層級

舉例,現在有個基本的html:
<div>
   <span>1</span>
   <span>2</span>
</div>
現在,我們採用事件委託:
$('div').on('click', 'span', fn);
該事件處理程序僅僅連接到 div 元素,由於 span 是在 div 裡面,對 span click 會往上泡浮到 div,並觸發 div 的 click 事件處理器,同時,剩下要做的就是檢查 event.target 是否符合我們指定的目標(範例中為 span)

看看更複雜點的範例:
<div id="parent">
    <span>1</span>
    <span>2 <b>another nested element inside span</b></span>
    <p>paragraph won't fire delegated handler</p>
</div>
下面是一些基礎邏輯:

// 對祖先附加處理程序
document.getElementById('parent').addEventListener('click', function(e) {
    // 過濾 event target
    if (e.target.tagName.toLowerCase() === 'span') {
        console.log('span inside parent clicked');
    }
});
上面的程式中,當 event.target 是被嵌套在過濾器裡面時就無法匹配(例如第二個span裡面有b,click她時,會被上面的程式過濾掉),所以我們需要一些迭代邏輯
document.getElementById('parent').addEventListener('click', function(e) {
    var failsFilter = true,
        el = e.target;
    while (el !== this && (failsFilter = el.tagName.toLowerCase() !== 'span') && (el = el.parentNode));
    if (!failsFilter) {
        console.log('span inside parent clicked');
    }
});












沒有留言: