我們通過 on 接口綁定一個事件的時候,內(nèi)部做了一些比較復(fù)雜的處理:
主要針對幾個設(shè)計問題的處理:
具體很多問題我們在后續(xù)課程中會一個一個解決,我們先看看如果同一個元素綁定多個相同或者不同的事件要如何處理?
首先我們腦海中先要有一個分離的概念,jQuery 的事件與數(shù)據(jù)其實是沒有直接關(guān)聯(lián)的關(guān)系,而且通過數(shù)據(jù)緩存去存儲事件數(shù)據(jù)的。jQuery 從1.2.3版本引入數(shù)據(jù)緩存系統(tǒng)貫穿內(nèi)部,為整個服務(wù)事件體系也引入了這個緩存機制,所以 jQuery 并沒有將事件處理函數(shù)直接綁定到 DOM 元素上,而是通過 .data 存儲在緩存 .cahce 上,所以事件的機制都是依賴之前的數(shù)據(jù)緩存模塊的。
我們?yōu)榱死斫?jQuery.event.add 代碼結(jié)構(gòu),適當(dāng)?shù)奶^這個環(huán)節(jié)中不能理解的代碼。
第一步:獲取數(shù)據(jù)緩存
//獲取數(shù)據(jù)緩存 elemData = data_priv.get( elem );
通過緩存對象的 get 方法獲取元素對應(yīng)的存儲數(shù)據(jù),如果沒有則內(nèi)部會新建一個與 elem 元素映射的數(shù)據(jù)緩存區(qū),用來存儲之后用戶將要要處理操作行為(事件與事件),這個處理主要是合并同個元素綁定多個事件的問題。
aaron.on('mousedown', 'li', function(e) { show('委托到li觸發(fā)') }) aaron.on('mousedown', 'ul', function(e) { show('委托到ul觸發(fā)') }) aaron.on('mousedown', 'div', function(e) { show('委托到div觸發(fā)') }) aaron.on('mousedown', function(e) { show('mousedown') })
如上同一個元素上綁定了 4 次不同的行為,但是都是針對同一個元素的所以這個地方我們就需要把事件與數(shù)據(jù)都合并到同一個緩存區(qū),這樣每次重復(fù)操作都不會在去創(chuàng)建一個新的緩存了。
第二步:創(chuàng)建編號
if( !handler.guid ) { handler.guid= jQuery.guid++; }
為每一個事件的句柄給一個標(biāo)示,添加 ID 的目的是用來尋找或者刪除 handler,因為這個東東是緩存在緩存對象上的,沒有直接跟元素節(jié)點發(fā)生關(guān)聯(lián)。
第三步:給緩存增加事件處理句柄
if ( !(events = elemData.events) ) { events = elemData.events= {}; } if ( !(eventHandle = elemData.handle) ) { eventHandle = elemData.handle = function( e ) { return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : undefined; }; }
events,eventHandle 都是 elemData 緩存對象內(nèi)部的,可見在elemData中有兩個重要的屬性:
之后的代碼無非就是對這 2 個對象的篩選、分組、填充了。
第四步: 填充事件名與事件句柄
事件名稱可以添加指定的 event namespaces(命名空間) 來簡化刪除或觸發(fā)事件。例如,"click.myPlugin.simple" 為 click 事件同時定義了兩個命名空間 myPlugin 和 simple。通過上述方法綁定的 click 事件處理,可以用 .off("click.myPlugin")
或 .off("click.simple")
刪除綁定到相應(yīng)元素的 Click 事件處理程序,而不會干擾其他綁定在該元素上的“click(點擊)” 事件。命名空間類似 CSS 類,因為它們是不分層次的;只需要有一個名字相匹配即可。以下劃線開頭的名字空間是供 jQuery 使用的。所以要針對每個事件都需要綁定。
如:
.on('mouseup mousedown','p',function(e){ console.log(e) })
其實就是填充events與eventHandle
elemData = { events:{} eventHandle:function(){} } handlers = events[type] = []; handlers.delegateCount = 0;
這段比較長了分解下,最終的目的就是為填充events,eventHandle。
其實整個 add 方法下來就干了那么幾件事:
所以我們可以看到在綁定的時候處理,都是為了后期做了大量的鋪墊。
請驗證,完成請求
由于請求次數(shù)過多,請先驗證,完成再次請求
打開微信掃碼自動綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書簽
舉報