我是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)  編輯  收藏 所屬分類: javascript 、Web開發

          評論

          # 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

          多謝分享  回復  更多評論   

          主站蜘蛛池模板: 宿迁市| 云梦县| 商水县| 崇仁县| 曲麻莱县| 铜鼓县| 湖南省| 河北区| 邢台县| 阿尔山市| 溧水县| 吉林市| 长阳| 隆昌县| 兰考县| 观塘区| 从化市| 三河市| 新郑市| 托克逊县| 金寨县| 嘉峪关市| 临泉县| 柳江县| 边坝县| 台湾省| 满洲里市| 永顺县| 施秉县| 拉萨市| 克拉玛依市| 夏津县| 武鸣县| 红安县| 龙南县| 东乡县| 呼和浩特市| 响水县| 宜兰县| 普定县| 寿宁县|