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