文章目錄
背景
接到了領導給的一個New Feature,為系統的菜單導覽列進行一些個人化的操作(滑鼠移到導覽功能表時下方出現子功能表,移到其他的菜單選項時顯示該選項的子功能表,隱藏其他子功能表。其次就是當使用滑鼠點擊一個菜單選項時就把該菜單及其子功能表固定,當滑鼠移出所有菜單選項的範圍是依然讓其顯示子功能表,再次點擊取消固定)。
原來的導覽列是使用ASP.NET Ajax的 HoverMenuExtender服務端控制項實現的。我們知道,服務端控制項的優點在於快速開發,但是缺點是不能夠進行個人化定製,且效率也是一個問題。最開始本來計劃在原有基礎上修改,但是發現該控制項無法滿足我們的個人化需求,所有決定使用jQuery來實現,並停止使用該控制項。這樣的好處是不需要修改背景代碼,只需要在前端增加JS指令碼就可以了。導覽列是在主版頁面中實現的,所以我使用的方案是在頁面HTML產生後,在前台使用jQuery動態綁定jQuery提供的mouseenter和mouseleave事件。
我們知道通過jQuery綁定事件的方式有很多種(one、tigger、on、delegate、live、bind等以及其對應的卸載事件方法),常用的有下面三種,其他的不外乎是它們的擴充和衍生,如下:
1 //直接註冊事件:2 target.eventType(function(){});3 //使用bind註冊事件4 target.bind(eventType,function(){});5 //使用delegate註冊事件6 parentTarget.delegate(target, eventType, function(){} );
第一種和第二種類似,在這剛開始的時候,我使用的是第二種方式來綁定事件,很快就實現的相應的效果。但是在測試的時候QA發現了一個bug:即當使用該導覽列頁面的表單提交,頁面進行了局部重新整理(使用updatepanel)之後,事件就失效了。當時還以為是頁面指令碼的載入問題,後來發現不是,因為指令碼已經被正確載入了。真正的原因是因為使用 .bind() ,選取器匹配的元素會被附加一個事件處理函數,而以後再添加的元素則不會有。為此需要再使用一次 .bind() 才行。
bind和delegate綁定事件的區別
如果頁面有局部重新整理想要對新產生的元素也能夠正確的綁定事件jQuery為我們提供了更多的選擇:1.3版本提供的live函數,1.4版本後提供了delegate函數,不過在1.7之後以即不再推薦使用live函數了,對於低版本jQuery可以使用delegate函數替代live,如果是1.7版本以上應該使用推薦的on函數。由於在項目中使用的是jQuery 1.4.1所有我只能使用delegate來實現了。
那麼使用bind和delegate來綁定事件二者有什麼區別的?使用 .bind() 時,選取器匹配的元素會被附加一個事件處理函數,而以後再添加的元素則不會有。為此需要再使用一次 .bind() 才行。而delegate方法通過事件委託來實現的:綁定在祖先元素上的事件處理函數可以對在後代上觸發的事件作出回應。只有在真的觸發該事件的時候delegate方法才會通過DOM樹去尋找對應的target元素,所有即使是後來添加(局部重新整理)的元素也依然能進行事件的綁定。由於現有項目使用的ASP.NET使用了大量的服務端控制項,所有我選擇綁定的容器是所有HTML元素的父元素"Body",核心代碼如下:
1 $("body").delegate(menuSelector, 'mouseleave', function() {2 //event binding3 });
參考資料&進一步閱讀
jQuery 1.9 API Documentation
作者:晴天豬
出處:http://www.cnblogs.com/IPrograming
本文著作權歸作者和部落格園共有,歡迎轉載,但請註明出處。