在事件處理中,很多地方都用到了這個 jQuery.event.special 方法,special 是一個在處理特殊的事件相當靈活,可以指定綁定和解開鉤子以及定制事件的默認行為,用這個 API 的時候可以創建自定義的事件但不僅僅是執行綁定事件處理程序時,引發這些“特殊”事件可以修改事件對象傳遞給事件處理程序,引發其他完全不同的事件,或者執行復雜的 setup 和 teardown 代碼當事件處理程序綁定到或未綁定元素。
某些事件類型的有特殊行為和屬性,換句話說就是某些事件不是大眾化的事件不能一概處理。
比如 load 事件擁有特殊的 noBubble 屬性,可以防止該事件的冒泡而引發一些錯誤,所以需要單獨針的處理,但是如果都寫成判斷的形式,顯然代碼結構就不合理了,而且不方便提供給用戶自定義擴展。有些瀏覽器并不兼容某類型的事件,如 IE6~8 不支持 hashchange 事件,你無法通過 jQuery(window).bind('hashchange', callback)
來綁定這個事件,這個時候你就可以通過 jQuery 自定義事件接口來模擬這個事件,做到跨瀏覽器兼容。這個就是 special 的作用了,又有點類似之前說的鉤子機制了。
原理
jQuery(elem).bind(type, callbakc)
實際上是映射到 jQuery.event.add(elem, types, handler, data)
這個方法,每一個類型的事件會初始化一次事件處理器,而傳入的回調函數會以數組的方式緩存起來,當事件觸發的時候,處理器將依次執行這個數組。
jQuery.event.add 方法在第一次初始化處理器的時候,會檢查是否為自定義事件,如果存在則將會把控制權限交給自定義事件的事件初始化函數,同樣事件卸載的 jQuery.event.remove 方法在刪除處理器前也會檢查此處。
初始化處事件處理器
if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) { if (elem.addEventListener) { elem.addEventListener(type, eventHandle, false); } }
卸載自定義事件
if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) { jQuery.removeEvent(elem, type, elemData.handle); }
jQuery.event.special 對象中,保存著為適配特定事件所需的變量和方法。
beforeunload: Object blur: Object click: Object focus: Object focusin: Object focusout: Object load: Object mouseenter: Object mouseleave: Object pointerenter: Object pointerleave: Object
事實上 jQuery 自定義事件那些接收的參數有點雞肋,需要 hack 與能 hack 的事件就那么一點點,且限制頗多,一般情況下很少使用到。
得出總結:
在 jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
方法中沒有傳遞回調對象是因為回調的句柄被關聯到了 elemData,也就是內部數據緩存中了,不難得出 jQuery 的事件綁定機制:jQuery 對每一個 elem 中的每一種事件,只會綁定一次事件處理函數(綁定這個elemData.handle),而這個 elemData.handle 實際只做一件事,就是把 event 丟到 jQuery 內部的事件分發程序。
jQuery.event.dispatch.apply( eventHandle.elem, arguments );
而不同的事件綁定,具體是由 jQuery 內部維護的事件列隊來區分(就是那個 elemData.events),在 elemData 中獲取到 events 和 handle 之后,接下來就需要知道這次綁定的是什么事件了。
請驗證,完成請求
由于請求次數過多,請先驗證,完成再次請求
打開微信掃碼自動綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書簽
舉報