jQuery對事件體系的修正不止是做了屬性兼容,重寫了事件的方法,還增加狀態機,那么這樣的處理有什么作用?
事件的核心的處理來了,實現委托
var aaron = $("#aaron") //同一個元素上綁定不同的事件委托 aaron.on('mousedown','p',function(e){ alert('委托到p觸發') e.stopPropagation() }) aaron.on('mousedown','ul',function(e){ alert('被阻止了') })
我們分析這個結構:
委托設計的問題
在通過 jQuery.event.add 方法的時候我們就知道,數據是被存儲在數據緩存 elemData 中,這樣我們不需要針對同一個元素上的每個事件都綁定 addEventListener,只需要把數據給分割好放到緩存中,所以同一個元素,不同事件,不重復綁定。
events = elemData.events = {}; eventHandle = elemData.handle = function(e) {};
數據都儲存在 elemData 的緩存里面,除此之外還有一個關鍵的處理如果 on 中傳入參數 selector ,意味著就是有委托的處理,那么我們就需要用一個標記來記錄下這個元素到底委托了多少次。
handlers.delegateCount++
可以看出就會自增,用來標記這個元素上有多少個委托的處理,用于后面的處理。
要實現委托,根據冒泡的原理,我們是不是應該把每一個節點層次的事件給規劃出來,每個層次的依賴關系?
所以 jQuery 引入了 jQuery.event.handlers 用來區分普通事件與委托事件,形成一個有隊列關系的組裝事件處理包{elem, handlerObjs}的隊列。
在最開始引入 add 方法中增加 delegateCount 用來記錄是否委托數,通過傳入的 selector 判斷,此刻就能派上用場了。
先判斷下是否要處理委托,找到委托的句柄。根據之前的測試 demo,在元素 DIV 下面嵌套了 P,然后 P 內嵌套了 A。
我們在觸發事件的時候,就會在事件緩存中取出這個元素所有對應的事件數據,然后就會分析這個數據的結構,是否有多個監聽,是否有委托關系
從圖我們可以得出:
那么事件的執行就需要有個先后,jQuery要如何排序呢?
依賴委托節點在 DOM 樹的深度安排優先級,委托的 DOM 節點層次越深,其執行優先級越高,委托的事件處理程序相對于直接綁定的事件處理程序在隊列的更前面,委托層次越深,該事件處理程序則越靠前。
請驗證,完成請求
由于請求次數過多,請先驗證,完成再次請求
打開微信掃碼自動綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書簽
舉報