【FT12短網址】事件代理:模式 or 反模式?
前言
終于熬過四個月了,人都黑了一圈。8 月 4 號的早讀文章由 @ 文藺翻譯授權分享。
正文從這開始~
JavaScript 工具包(toolkit)和框架所做的大量工作,都集中于嘗試修復、規范或優化瀏覽器的功能實現。此類工作需要做出許多假設,這些假設包括:問題是什么,開發人員將如何使用我們的工具,以及我們對未來的期望。
但這些假設經常是錯誤的。更有甚者,在很長一段時間內,這些選擇可能貌似正確,直至某天我們被問題反咬一口。在這個無知的幸福時期當中,我們的工具包可能變得相當受歡迎,并成為大型復雜代碼庫的重要組成部分。
事件冒泡與事件代理
事件冒泡允許源自子節點的事件向父級節點“冒泡”(bubble)。這種行為導致 JavaScript 開發者使用松散的設計模式來識別我們所關心的接收事件的節點 —— 通常使用 CSS 選擇器 —— 同時將事件監聽器添加到該節點的父級節點上。
一旦這種模式進入工具包之中,設計 API 時須做出一些假設。在開始階段,這些假設主要圍繞性能與效率展開。
事件代理(Event Delegation)是處理事件的實際方法之一。然而,這種方法論適用于所有項目嗎?實際上,更好的問題可能是,每個工具包的所基于的假設是否與你的項目需求相符。要想知道某個 API 是否適合當下項目,就要了解這些工具是建立在哪些假設之上的,并且理解每個工具包如何解釋它們。
假設
一起來看看,在思考如何有效管理 DOM 事件時可能會產生的一些假設。
本機事件注冊機制太慢
在你能夠提出 API 存在的繼發原因之前,不要創建新的 API。隨著瀏覽器廠商們對運行時的投入增加,你的功能實現總有一天會比原生實現慢。我所在的 SitePen 有一個項目依賴于數組拼接(splice)速度。我們發現,在某些情況下,手動操作索引和數組長度能夠帶來顯著的性能提升。但我們無法定位到特定瀏覽器、瀏覽器版本或平臺,因為無法進行運行時功能測試以確定我們的實現是否比原生 API 快。
新的原生 API 不會出現
保持謹慎,確保已收集到足夠的信息,可以降級使用原生實現 —— 無論是已存在的,還是理想情況下可能存在的。這項工作的另一個名字叫“預防過時”(future proofing)。在某些情況下,你可能會使用必需參數超出絕對需要的 API,但如果它l能夠保證輕松地過渡到更優秀的原生 API,那么完全可以如此。一個很好的例子是最終獲得原生支持的 querySelectorAll API,之前許多開發人員假設這種事永遠不會發生。
不常見用例沒有性能損失
事件代理可能會以數種方式呈現。例如兩種特殊情況:大量節點上的少量事件,以及少數節點上的大量事件。如果針對其中之一進行優化,則可能會為另一個帶來明顯的瓶頸。雖然使用事件代理可能只需要向單個節點添加一個事件偵聽器,但識別觸發回調的節點的復雜方法對性能的影響可能不成比例??焖儆|發大量事件(例如鼠標移動或滾動事件)正是使用事件代理的場景。
條件與背景
在考慮事件代理時,很容易認為我們只需要關心用戶交互。這可能導致我們假設節點始終是文檔的一部分,然后開始思考,為何不在 document 對象上添加單個事件處理程序呢?DOM 事件并非總是用戶交互的結果 —— 我們也有人為事件、自定義事件以及加載事件等。如果想要監聽的節點不在文檔中,而監聽器卻綁定在 document 對象上,我們永遠得不到通知。如果在 API 中無法區別監聽器是添加到 document 上,抑或是添加到我們所傳遞的參數上,則能夠理解為什么會出現這種情況。
抽象
如果一個工具包提供一個僅用于支持代理的事件處理 API —— 需要父級節點和標識子節點的選擇器 —— 則無法將事件監聽器直接添加到某個節點。即使是使用 CSS 選擇器,也引入了更高級的功能,可以輕松地使用另一種選擇器語法或簡單函數。
不會發生副作用
如上所述,DOM 事件冒泡是事件代理模式存在的前提。但是了解完整規范所涉及的內容之后,你會發現,事件冒泡是可以取消的。你的實現可能會將 stopPropagation 方法為空函數的自定義事件傳遞給回調函數;或者,你可能只會記錄問題,并限制事件代理 API 的使用。這兩種方法都有問題,但是如果你打算像為 document 對象事件處理程序那樣工作,添加大量可取消的事件層可能放大副作用。
不受時間影響
一旦代碼編寫完成,很可能就會棄而不顧。但瀏覽器正在以我們無法想象、預測的方式向前發展,我們在編寫代碼時所做的假設可能會被證明是錯誤的,盡管我們盡了最大的努力。
總結
為什么要在項目中使用事件代理?
原生實現太慢了嗎?對現代瀏覽器來說不太可能。
是否有更好的 API 來執行事件代理?目前還沒有 —— 如果你需要事件代理,這是一個很好的模式。
該工具包的性能優化是否符合項目需求?如果它專注于特殊情況,可能不會。
工具包的實現中有沒有什么不適用于你的項目的內容?閱讀文檔,這些通常都會標出。
是否有副作用?遇到錯誤前你可能不會發現這一點,所以要特別注意。
人們在不了解創作假設的情況下,所有設計模式都有成為反模式的風險,所以對項目中使用的任何新工具都應當回答同樣的問題。如果你所做的似乎是在抄近路,要特別小心。謹慎、多加思考,才能使項目發光。
掃描二維碼推送至手機訪問。
版權聲明:本文由短鏈接發布,如需轉載請注明出處。
本文鏈接:http://www.virginiabusinesslawupdate.com/article_377.html