zoukankan      html  css  js  c++  java
  • 事件委托(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 + "
     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>   
    
  • 相关阅读:
    (转载)显示调用构造函数和析构函数
    (转载)c库不正确问题
    (转载)LINUX UNBUNTU10.04 下 搭建OC编译环境
    (转载)Chrome 快捷键 整理版
    (转载)php循环检测目录是否存在并创建(循环创建目录)
    (转载)PHP 判断常量,变量和函数是否存在
    Dockerfile 指令
    JavaEE&Docker 容器示例
    docker 中运行 redis 服务
    docker 中运行 sshd 服务
  • 原文地址:https://www.cnblogs.com/waisonlong/p/5318925.html
Copyright © 2011-2022 走看看