CONAN ZONE

          你越掙扎我就越興奮

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            0 Posts :: 282 Stories :: 0 Comments :: 0 Trackbacks
          眾所周知, 瀏覽器中內存泄露以及內存無法回收(兩者不是一回事,很多人都把他們弄混淆了),常常是由于對dom元素注冊事件不當引起的.

          通常的解決方案是, 自行實現一套 添加事件, 移除事件 以及刪除dom元素的機制.
          為dom元素添加事件時, 同時記錄 這個事件 以及對應的函數,
          在刪除dom元素時, 先移除dom元素上已經添加的事件 再刪除dom元素本身.

          而當頁面中添加了事件監聽的dom元素很多時, 移除元素變得很麻煩.
          例如 一個div 里面有個form form里有多個元素都添加了事件.
          那么移除這個div時, 就要先去移除他下面每一個元素上的事件 然后再移除這個div.

          這種做法很多時候是必須的, 而且自己寫一個"深度遍歷子節點,并移除其事件"的函數也并不是很困難.

          但是 在很多時候 這種做法是可以避免的, 避免的方法就是, 把事件監聽注冊到更上層的dom元素中.
          并且在事件函數中 通過 event.target/event.srcElement 來 事件發生在哪個元素上,然后來執行相關的方法.
          這樣 在移除元素時 只要移除這個元素以及它上面的事件 就可以了, 而不必執行(或者少量的執行)"移除所有子節點事件"的動作了.


          見下面的例子 :

          Html代碼 復制代碼
          1.  <table width="300" border="1"  onclick="showDetail(event)">    
          2.  <tr>  
          3. <td>1</td>  
          4. <td>Tom</td>  
          5. <td><input type="button" value="詳細信息" userid="1" /></td>  
          6.  </tr>  
          7.  <tr>  
          8. <td>2</td>  
          9. <td>Kate</td>  
          10. <td><input type="button" value="詳細信息" userid="2"  /></td>  
          11.  </tr>  
          12.  <tr>  
          13. <td>3</td>  
          14. <td>John</td>  
          15. <td><input type="button" value="詳細信息"  userid="3" /></td>  
          16.  </tr>  
          17.  </table>  


          在這個例子中, 實際上事件只是注冊在table上, 而沒有在"input type="button"上.

          "showDetail" 可以這樣寫

          Javascript代碼 復制代碼
          1. function showDetail_b(event) {   
          2.     event=event||window.event;   
          3.     var target=event.target||event.srcElement;   
          4.     if ( String(target.tagName).toLowerCase()=='input' &&  target.value=="詳細信息") {   
          5.         showUserDetail(target.getAttribute('userid') );   
          6.     }   
          7. }  



          當然 這種做法不是絕對的, 有時候這么做很可能讓代碼變得臃腫冗長.
          到底是否使用"事件上提"的做法 要根據實際情況來選擇.
          不過 根據我的以往經驗, 在列表(table)中, 使用這種技術非常合適.
          因為 列表有著"行與行之間模型一致"(只是數據不一致,結構一致)的特點.

          例如,下面的效果, 都可以通過在 table上注冊事件來實現:

          1 點擊行, 行變色 (不必在 tr 上注冊點擊事件)
          2 點擊行中的某個按鈕 (不必在 tr 里的 button 上注冊點擊事件)
          3 鼠標經過行時 行變色 (不必在 tr上注冊 mouseover/mouseout 事件, 而是可以在table上注冊mousemove事件)
          4 還有關于單元格的 很多效果.....

          當然,在非列表里 這種做法也有很多的用武之地.
          總之 合理的利用"事件上提"的方法, 可以增強dom元素和事件的可控性, 有效的防止內存泄露和內存無法回收的情況.
          posted on 2008-07-23 23:03 CONAN 閱讀(205) 評論(0)  編輯  收藏 所屬分類: JS
          主站蜘蛛池模板: 瑞昌市| 通榆县| 同江市| 大新县| 赤壁市| 岫岩| 天门市| 贡嘎县| 河东区| 华坪县| 隆林| 中宁县| 陇南市| 黄大仙区| 宁城县| 望奎县| 社旗县| 无为县| 额济纳旗| 和静县| 陕西省| 大新县| 禹州市| 光泽县| 湟中县| 五指山市| 安吉县| 白朗县| 抚顺县| 尼玛县| 敦化市| 福贡县| 襄汾县| 郯城县| 旅游| 紫云| 札达县| 黄陵县| 平利县| 安塞县| 宣化县|