事件委托(js实现)

1.事件委托的作用

事件委托的意义:,事件就是onclick,onmouseover,onmouseout等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件。利用冒泡的原理,把事件加到父级上,触发执行效果。

也就是:利用冒泡的原理,把事件加到父级上,触发执行效果。

2.下面是网上择抄的一个例子:

<ul id="ul">
  <li>aaaaaaaa</li>
  <li>bbbbbbbb</li>
  <li>cccccccc</li>
</ul>

js部分:

window.onload = function(){
  var oUl = document.getElementById("ul");
  var aLi = oUl.getElementsByTagName("li");

  for(var i=0; i<aLi.length; i++){
    aLi[i].onmouseover = function(){
      this.style.background = "red";
    }
    aLi[i].onmouseout = function(){
      this.style.background = "";
    }
  }
}

这样我们就可以做到li上面添加鼠标事件。

但是如果说我们可能有很多个li用for循环的话就比较影响性能。

下面我们可以用事件委托的方式来实现这样的效果。html不变

首先看看在jquery中的写法:

$('#ul').on('mouseover','li',function(){
    $(this).css('background','red'); 
});
$('#ul').on('mouseout','li',function(){
    $(this).css('background',''); 
});

jquery的写法非常简单,快捷,但是jquery写多了,就快连js也忘了怎么写。

window.onload = function(){
  var oUl = document.getElementById("ul");
  var aLi = oUl.getElementsByTagName("li");

/*
这里要用到事件源:event 对象,事件源,不管在哪个事件中,只要你操作的那个元素就是事件源。
ie:window.event.srcElement
标准下:event.target
nodeName:找到元素的标签名
*/
  oUl.onmouseover = function(ev){
    var ev = ev || window.event;
    var target = ev.target || ev.srcElement;
    //alert(target.innerHTML);
      alert(target.nodeName);
    if(target.nodeName.toLowerCase() == "li"){
    target.style.background = "red";
    }
  }
  oUl.onmouseout = function(ev){
    var ev = ev || window.event;
    var target = ev.target || ev.srcElement;
    //alert(target.innerHTML);
    if(target.nodeName.toLowerCase() == "li"){
    target.style.background = "";
    }
  }
   }

3.事件委托说到底是用了target来添加事件处理,但是由于ie永远不按标准走,上面已经对其做了兼容,

ie:window.event.srcElement
标准下:event.target

在这里先说说target与currentTarget的区别
标准情况下,target在事件流的目标阶段;currentTarget在事件流的捕获,目标及冒泡阶段。只有当事件流处在目标阶段的时候,两个的指向才是一样的, 而当处于捕获和冒泡阶段的时候,target指向被单击的对象而currentTarget指向当前事件活动的对象(一般为父级)。
网上的一个例子:
 <div id="outer" style="background:#099">  
         click outer  
         <p id="inner" style="background:#9C0">click inner</p>  
         <br>  
     </div>  
       
     <script type="text/javascript">  
     function G(id){  
          return document.getElementById(id);      
    }  
    function addEvent(obj, ev, handler){  
         if(window.attachEvent){  
            obj.attachEvent("on" + ev, handler);  
        }else if(window.addEventListener){   
             obj.addEventListener(ev, handler, false);  
        }  
     }  
     function test(e){  
         alert("e.target.tagName : " + e.target.tagName + "\n e.currentTarget.tagName : " + e.currentTarget.tagName);  
     }  
     var outer = G("outer");  
     var inner = G("inner");  
     //addEvent(inner, "click", test);  
    addEvent(outer, "click", test);  
    </script>  

上面的示例中,当在outer上点击时,e.target与e.currentTarget是一样的,都是div;当在inner上点击时,e.target是p,而e.currentTarget则是div。

如果在ie中,window.event.srcElement就等于标准下的e.target

那么e.currentTarget呢?IE9之前都不兼容currentTarget

下面是两种兼容方法

1)修改this指针,并在IE下将ad1赋值给event.currentTarget

<a id="ad1" data-at="1" href="">
    <span id="span1">demo</span>
</a>
<script>
   var ad1 = document.getElementById("ad1");
    var addListener = (function() {
        if(document.attachEvent) {
            return function(element, event, handler) {
                element.attachEvent('on' + event, function() {
                    var event = window.event;
                    event.currentTarget = element;
                    event.target = event.srcElement;
                    handler.call(element, event);
                });
            };
         }
         else {
            return function(element, event, handler) {
                element.addEventListener(event, handler, false);
            };
         }
    }());
    
  addListener(ad1,"click",function(e){
    var currentTarget = e.currentTarget;
    var at =0;
    if(currentTarget.dataset){
        at = currentTarget.dataset.at
    }else{
        at = currentTarget.getAttribute("data-at");
    }
    alert(at)
  })
 </script>  

2)向上寻找父元素

<script>
    var ad1 = document.getElementById("ad1");
    ad1.onclick = function(e){
    var e = e || window.event;
    var target = e.target || e.srcElement;
    if(target.tagName.toLowerCase != "a"){
        target = target.parentNode
        }
    alert(target.id) // ad1
    var at = 0;
    if(target.dataset){
        at = target.dataset.at
    }else{
        at = target.getAttribute("data-at");
    }
    }
</script>   

 

posted @ 2016-03-25 12:06  waisonlong  阅读(1944)  评论(0编辑  收藏  举报