否-您不應將所有委托的事件處理程序綁定到document
對象。這可能是您所能創建的最糟糕的執行場景。
首先,事件委托并不總是使代碼更快。在某些情況下,它是有利的,在某些情況下不是。當您實際需要事件委托并從中受益時,您應該使用事件委托。否則,您應該將事件處理程序直接綁定到事件發生的對象,因為這通常會更有效。
其次,不應在文檔級別綁定所有委托事件。這就是為什么.live()
被否決,因為這是非常低效的,當你有很多事件這樣綁定。對于委托事件處理,將它們綁定到非動態的最接近的父級更有效。
第三,并不是所有的事件都可以通過委托解決所有的問題。例如,如果您想攔截輸入控件上的鍵事件并阻止無效鍵被輸入到輸入控件中,則不能使用委托的事件處理來執行此操作,因為當事件冒泡到委托處理程序時,輸入控件已經對其進行了處理,而且影響該行為為時已晚。
在這里,事件委托是必需的或有利的:
- 當您捕獲事件的對象被動態創建/刪除時,您仍然希望捕獲事件,而不必每次創建新事件時都顯式地重新綁定事件處理程序。
- 當您有很多對象都需要完全相同的事件處理程序時(其中很多對象至少是數百個)。在這種情況下,在安裝時綁定一個委托事件處理程序可能比綁定數百個或更多直接事件處理程序更有效。注意,與直接事件處理程序相比,在運行時委托事件處理總是效率較低.
- 當您試圖捕獲(文檔中較高級別的)發生在文檔中任何元素上的事件時。
- 當您的設計顯式地使用事件冒泡和停止傳播()來解決頁面中的一些問題或特性時。
要進一步了解這一點,需要了解jQuery委托的事件處理程序是如何工作的。當你這樣說的時候:
$("#myParent").on('click', 'button.actionButton', myFn);
類上安裝一個通用jQuery事件處理程序。#myParent
對象。當單擊事件冒泡到此委托事件處理程序時,jQuery必須遍歷附加到此對象的委托事件處理程序列表,并查看事件的原始元素是否與委托事件處理程序中的任何選擇器匹配。
由于選擇器可能相當復雜,這意味著jQuery必須解析每個選擇器,然后將其與原始事件目標的特征進行比較,以確定它是否與每個選擇器匹配。這不是一個廉價的行動。如果只有一個選擇器,那么這沒什么大不了的,但是如果將所有選擇器都放在Document對象上,并且與每一個冒泡事件相比有數百個選擇器,那么這可能會嚴重阻礙事件處理性能。
因此,您希望設置委托的事件處理程序,以便委托的事件處理程序盡可能接近目標對象。這意味著在每個委托事件處理程序中會出現更少的事件,從而提高性能。將所有委托事件放到文檔對象上是最糟糕的性能,因為所有冒泡事件都必須遍歷所有委托事件處理程序,并根據所有可能的委托事件選擇器進行評估。這就是為什么.live()
不受歡迎,因為這是.live()
事實證明是非常低效的。
因此,要實現優化的性能:
- 只有在實際提供所需的功能或提高性能時,才使用委托事件處理。不要總是使用它,因為它很容易,因為當你真的不需要它。實際上,它在事件分派時執行的性能比直接事件綁定差。
- 盡可能將委托的事件處理程序附加到最近的父級到事件源。如果由于具有要捕獲事件的動態元素而使用委托事件處理,則選擇本身不動態的最近的父級。
- 對委托事件處理程序使用容易評估的選擇器。如果您遵循委托事件處理的工作方式,您將了解到,必須將委托的事件處理程序與許多對象進行多次比較,因此盡可能高效地選擇器或向對象添加簡單的類,從而可以使用更簡單的選擇器,將提高委托事件處理的性能。