YUI的事件代表團3
2009年11月13日下午02:31 Caridy帕蒂諾| 開發 | 6評論越來越多的Web應用與 AJAX的需求加載的內容或注入元素的DOM片段,以更新舊的內容與新的內容。 如果新的內容,包括某些JavaScript功能-例如,鏈接,觸發彈出覆蓋-我們需要添加事件處理程序的內容被插入後,刪除這些新的內容之前, 為了避免在IE內存洩漏。 這些“事件代表團”中扮演一個Web應用程序的重要作用。
一個用例
考慮一個widget,顯示從最新的鳴叫YUI的開發 。 該列表是代表一個ul元素,每個鳴叫是由代表li元素。
該列表被刷新,每2分鐘使用AJAX和用戶可以使用搜索框過濾列表。 如果用戶點擊頭像圖片或個人資料的鏈接,我們要顯示更多的信息在YUI的疊加 。
簡單的解決方案
使用YUI 3,它是簡單的,盡快為他們成為直接的元素,添加事件監聽器:
Y.on(“點擊”,handleClick,“a.profile”); 正如你可以看到,這是非常簡單。 但是,我們會做到這一點,每次改動的內容,這增加了我們的代碼的開銷,更遑論需要刪除每一個Y.detach()替換舊的內容之前,的。
冒泡技術
事件冒泡的優勢,我們可以添加一個偵聽到一個容器元素, document文件,甚至趕上泡沫鏈上的事件。 在回調函數中,我們會分析事件的目標來確定,如果我們期待在執行我們的覆蓋代碼之前(通過類名或ID)。
這種技術減少了每個元素添加事件監聽器的DOM開銷,但我們仍然需要我們的回調函數內適當的目標容器和過濾器來分析每一個點擊,前一陣子,我寫了一篇有關這項技術的文章,解釋詳細介紹了如何冒泡庫YUI的擴建工程。
但是,這並不是新的,已經是一個廣泛使用的概念。 那麼,什麼是新銳 3?
介紹Y.delegate()
銳3,引入了一個新的delegate() (),它是基於事件代表團原則,並採用熟悉的語法:
/ /定義每個元素的簡單的聽眾: Y.on(“點擊”,handleClick, “#容器UL李a.profile”); / /使用委託()方法的容器中定義的監聽器: Y.delegate(“點擊”,handleClick, “#容器”,“UL李a.profile');
這裡的區別是delegate()事件冒泡的優勢,適用於一個容器元素(一個'#container'容器“),但它不會停止。 當事件觸發時,每一個目標是對給定的選擇( 'ul li a.profile'相匹配的回調之前執行。 正如你可以看到, handleClick()的函數定義為回調函數可以為這兩種技術相同 。 從回調的角度來看,分歧歸事件實用程序。 下面是這種視覺描述:
/ /標記 <div id="container"> <UL> <LI> <a href="avatar1.html" class="profile"> <img src="1.jpg"/> </ A> <a href="username1.html" class="username">名稱 1 </ A> </ LI> <LI> <a href="avatar2.html" class="profile"> <img src="2.jpg" /> </ A> <A href="username1.html" class="username">名稱 1 </ A> </ LI> </ LI> <LI> <a href="avatar3.html" class="profile"> <img src="3.jpg" /> </ A> <A href="username1.html" class="username">名稱 1 </ A> </ LI> </ LI> </ UL> </ DIV>
如果我們點擊第二個頭像圖片ul li a img IMG),事件了DOM樹中的a與類"profile" “鏈接,並回調handleClick()被調用。 無論所使用的技術,它接收相同的事件門面結構:
/ /標記
handleClick =功能(E){
/ / e.target - > IMG:實際點擊目標
/ / e.currentTarget - >錨元素的
/ /監聽器被連接到(點擊),
/ /或相匹配的元素
/ /代表團規範(委託:按一下)。
}; 性能提升
這一新功能使我們能夠大幅提高性能,尤其是在兩個領域:
- 降低初始加載時間多個子元素時,需要事件處理
- 降低運行時間由用戶交互引起的動態注射
在這兩種情況下,可以得到改進減少 DOM的交互。 由於 JavaScript引擎得到更快的DOM瓶頸的現實依然存在。 3 YUI的事件代表團移動遍歷 DOM樹從加載過程中用戶交互的開銷,並減少消除需要在回調的目標相匹配元素的複雜性。 相反, delegate()測試事件的目標( e.target對選擇() 'ul li a.profile'的事件被觸發後,但回調之前執行,這尤其適用於複雜的DOM結構。
實施這背後真正的美,正如我之前提到的,是回調簽名完全相同。 我們不需要改變的代碼delegate() )到我們的代碼。 我們只需要改變的聽眾是如何定義和YUI 3將做休息。
添加功能
如果我們還想要顯示的配置文件覆蓋時,Twitter用戶名,這是一個帶班的主要用戶"username" “,我們只需要添加更多的選擇,最後一個參數:
Y.delegate(“點擊”功能(E){ / / e.target - >目標節點 / / e.currentTarget - >匹配的節點 / / e.container - >容器節點(在這種情況下,“#容器”) / / e.currentTarget.get(“類名”) - >“配置文件”或“username” e.halt(); / /速記 stopPropagation()的preventDefault() }“#容器”,“UL李a.profile,UL李a.username”);
事件代表團回調是類似於一個簡單的監聽回調,但它也提供了更多的信息,通過事件門面對象一樣e.container代表事件被抓的元素。
代表作為節點的插件
在相同的方式on()不僅是可用Y Y實例,而且在YUI節點實例級別, delegate()也可作為一個節點插件的。 下面是一個例子:
/ /使用YUI3節點代表插件: Y.one(“#容器”)委託(“點擊”,handleClick,“UL李a.profile”);
只要確保包括在您的use() "node"或"node-event-delegate" ,和功能將被加載在沙箱中使用的語句。 另外還要注意delegate()可以與其他事件泡在DOM中,甚至為那些使用YUI的事件實用程序模擬像focus焦點blur模糊。
結論
代表團delegate()的事件是一個很酷的功能,特別是對於那些希望創建了大量的用戶交互和AJAX功能複雜的應用程序。 這也是在您的應用程序後沒有任何開銷或額外的複雜性,在您的代碼,例如在性能優化過程中,可以引入。 最後,你應該知道,大部分銳 3即將到來的部件一定會從一開始就採取這種技術的優勢。
分享和擴展: 書籤del.icio.us | Digg它! | 書籤交易!
6評論
抱歉,評論形式此時關閉。



這是偉大的!
你聯繫我一次,但我從來沒有到您的鼓泡圖書館鴿子為 YUI2。
對於我來說,這將是“拉門”鏈接的回調處理特別有用。 1-5類名的任何地方處理拉門鏈接 EM / SPAN / IMG和處理分組鏈接浮現在腦海中。 例如:
http://css-tricks.com/forums/viewtopic.php?f=5&t=3965
評論由 Josh 大號 - 2009年11月13日#
我相信你軋製成2.8分支代表()以及(我當然希望如此,因為我用它:))。。
評論感謝- 2009年11月14日,日#
是的,你說得對,“委託”銳 3.0測試版推出,並已進入銳 2.8回遷。 下面是完整的信息:
http://developer.yahoo.com/yui/event/#委託
評論Caridy帕蒂諾 - 2009年11月14日,日#
這是偉大的。 我們使用的是冒泡庫 2.1,我不知道如果是尚未與 YUI2.8兼容。
addDefaultAction方法上使用()或委託()嗎?
YAHOO.Bubbling.addDefaultAction(“容器”,handleClick);
再次整齊的解釋。 謝謝。
評論Binesh Gummadi - 2009年11月16日#
[...]我從來沒有使用YUI庫(還),但新的事件代表團銳 3.0功能,看它有一個很好的的:/ /定義每個元素的簡單的聽眾:Y.on(“點擊” [... ...]
Pingback由事件代表團銳3.0 | TopicObserver.com - 2009年11月16日, #
@ Binesh:此功能在銳 3.0內置的解決方案,它的不冒泡庫相關。 是的,你可以使用它以類似的方式。 下面是一個例子:
Y.delegate('click', function(e) {
// e.currentTarget -> matching node
e.halt();
}, 'document', 'a.actionPopup, button.actionPopup');
在這種情況下,這是一個在文檔級別的全球監聽器,觸發的動作,如果用戶點擊一個鏈接或一個按鈕類“actionPopup”。 這將是“YAHOO.Bubbling.addDefaultAction”非常相似,但在一個更一致的方式。 :-)
評論Caridy帕蒂諾 - 2009年11月16日, #