我是FE,也是Fe

          前端來源于不斷的點滴積累。我一直在努力。

          統計

          留言簿(15)

          閱讀排行榜

          評論排行榜

          jQuery中的delegate與live實現方式簡析

          delegatelive方法是jQuery在1.4版本中新增的方法。他的作用是事件監聽,但是可以對jQuery對象中新增的DOM對象也作用:

          <script>
              $(
          "body").delegate("p""click"function(){
                $(
          this).after("<p>Another paragraph!</p>");
              });
          </script>

          上面的這個demo運行效果就是點擊一個段落P標簽將在p標簽后面添加一個p標簽,對于新增的p標簽同樣可以點擊新增一個p標簽,新增的標簽不需要監聽其click事件。live也同理:


              $(
          "p").live("click"function(){
                $(
          this).after("<p>Another paragraph!</p>");
              });

          這個是怎么實現的了?我自己嘗試了一把:首先必須了解事件的冒泡機制。下面的例子將在按鈕 和其容器上同時監聽click事件,根據冒泡的做法,將先觸發按鈕的click事件,然后觸發容器div的click事件。

          window.onload = function(){
                      
          function handle(e){
                          
          //獲取event對象
                          //標準DOM方法事件處理函數第一個參數是event對象
                          //IE可以使用全局變量window.event
                          var evt = window.event?window.event:e;

                          
          //獲取觸發事件的原始事件源
                          //標準DOM方法是用target獲取當前事件源
                          //IE使用evt.srcElement獲取事件源
                          var target = evt.target||evt.srcElement;

                          
          //獲取當前正在處理的事件源
                          //標準DOM方法是用currentTarget獲取當前事件源
                          //IE中的this指向當前處理的事件源
                          var currentTarget= e?e.currentTarget:this;

                          
          //問題:在IE 9下  window.event 與 e 不同 evt沒有currentTarget屬性,e才有currentTarget屬性(視為標準瀏覽器做法??)
                          alert("src id:"+target.id+"\ncurent target id :"+currentTarget.id);

                          
                      }
                      document.getElementById(
          "btn").onclick=handle;
                      document.getElementById(
          "c").onclick= handle;
                      
                  }
          <div id="c" class="">
              
          <input type="button" id="btn" name="" value="button"  />
          </div>

          問題在于處理容器c的click事件是由冒泡觸發的。需要找到真正觸發事件的事件源按鈕btn。標準瀏覽器的event提供了currentTarget屬性獲取原始事件源。否標準瀏覽器IE6/7/8可以直接使用this訪問。這樣div的click事件中可以獲取到真正觸發事件的事件源。

          //ps:上面的代碼中有個發現:在調試的時候發現IE 9中的e 和全局變量window.event有區別,IE 9的e的設置完全是按照標準瀏覽器來的。所以e也提供了currentTarget屬性。下面是我調試時候的發現:

           

          其實只要能獲取到冒泡的原始事件源,對于新增的元素,我們通過監聽其父容器事件,然后根據原始事件是否是新增元素,就可以觸發新增元素的事件。這就是所謂的“代理(delegate)”,就是通過容器(未必是父容器)的事件監聽代理新元素的事件。下面用一個超鏈接新增一個按鈕并且在不監聽其事件情況下通過事件冒泡捕獲其事件。

          window.onload = function(){
                      
          function handle(e){
                          
          //獲取event對象
                          //標準DOM方法事件處理函數第一個參數是event對象
                          //IE可以使用全局變量window.event
                          var evt = window.event?window.event:e;

                          
          //獲取觸發事件的原始事件源
                          //標準DOM方法是用target獲取當前事件源
                          //IE使用evt.srcElement獲取事件源
                          var target = evt.target||evt.srcElement;

                          
          //獲取當前正在處理的事件源
                          //標準DOM方法是用currentTarget獲取當前事件源
                          //IE中的this指向當前處理的事件源
                          var currentTarget= e?e.currentTarget:this;

                          
          //問題:在IE 9下  window.event 與 e 不同 evt沒有currentTarget屬性,e才有currentTarget屬性(視為標準瀏覽器做法??)
                          alert("src id:"+target.id+"\ncurent target id :"+currentTarget.id);

                          
          if(target.id=="newbutton"){
                              alert(
          "觸發新增元素的delegate方法");
                          }

                      }

                      document.getElementById(
          "btn").onclick=handle;
                      document.getElementById(
          "c").onclick= handle;


                      document.getElementById(
          "btnadd").onclick=function(){
                          
          var btn = document.createElement("input");
                          btn.setAttribute(
          "value","點擊我試試");
                          btn.setAttribute(
          "type","button");
                          btn.setAttribute(
          "id","newbutton");
                          
          //沒有監聽新按鈕的onclick事件
                          document.getElementById("c").appendChild(btn);
                      }

                  }
          <div id="c" class="">
              
          <input type="button" id="btn" name="" value="button"  />
          </div>
          <href="###" id="btnadd">添加一個按鈕</a>

          新增的按鈕同樣能監聽到其click方法,只是使用其父容器代理click事件在代理新按鈕的click事件

          上面的分析也能說明為什么delegate的性能會比live要好。因為live是通過document.body的事件代理了新元素的事件。delegate指定了事件代理的夫容器,這樣事件冒泡的層次會少,性能表現會好。

           

          posted on 2011-04-19 12:07 衡鋒 閱讀(4762) 評論(3)  編輯  收藏 所屬分類: javascriptWeb開發

          評論

          # re: jQuery中的delegate與live實現方式簡析 2011-04-20 15:37 網購打折促銷信息

          最近正在學jquery,多謝分享。  回復  更多評論   

          # re: jQuery中的delegate與live實現方式簡析 2011-04-21 15:02 好看的電影

          感覺有點難度  回復  更多評論   

          # re: jQuery中的delegate與live實現方式簡析 2011-09-16 08:23 tb

          多謝分享  回復  更多評論   

          主站蜘蛛池模板: 南皮县| 碌曲县| 沧州市| 电白县| 宁陵县| 黄龙县| 额尔古纳市| 长垣县| 百色市| 博罗县| 泗阳县| 扶余县| 招远市| 合肥市| 扬中市| 乌恰县| 南岸区| 抚宁县| 斗六市| 永德县| 邵阳县| 伊通| 霍邱县| 隆林| 鸡泽县| 舞阳县| 海口市| 甘孜县| 沙雅县| 清徐县| 勃利县| 儋州市| 云龙县| 玉门市| 南充市| 嵩明县| 贵港市| 蒲江县| 平潭县| 繁峙县| 永靖县|