zoukankan      html  css  js  c++  java
  • 事件委托

    事件委托是指利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件,例如公司所有同事都委托前台领取快递,这样就只需要一个人收快递并负责转交给同事,而不用所有人都带公司门口去收快递。

    在下面的例子中,包含了4个被单击后会执行操作的input框,按照传统做法,需要逐一添加事件处理程序

    <div id="box">
       <input type="button" id="add" value="添加" />
       <input type="button" id="remove" value="删除" />
       <input type="button" id="move" value="移动" />
       <input type="button" id="select" value="选择" />
    </div>
    window.onload = function(){
        var Add = document.getElementById("add");
        var Remove = document.getElementById("remove");
        var Move = document.getElementById("move");
        var Select = document.getElementById("select");
                
        Add.onclick = function(){
            alert('添加');
        };
        Remove.onclick = function(){
            alert('删除');
        };
        Move.onclick = function(){
            alert('移动');
        };
        Select.onclick = function(){
            alert('选择');
        }
    }

    如果在一个复杂的程序中,对所有的单击元素都采用这种方式,那么结果就是会有数不清的代码用于添加事件处理程序,此时,我们就可以利用事件委托来解决这个问题,只需要在DOM树中尽量最高层级上添加一个事件处理程序即可。

    window.onload = function(){
            var oBox = document.getElementById("box");
            oBox.onclick = function (ev) {
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement;
                if(target.nodeName.toLocaleLowerCase() == 'input'){
                    switch(target.id){
                        case 'add' :
                            alert('添加');
                            break;
                        case 'remove' :
                            alert('删除');
                            break;
                        case 'move' :
                            alert('移动');
                            break;
                        case 'select' :
                            alert('选择');
                            break;
                    }
                }
            }
        }

     性能优化

    在下面有4个列表项,我们希望为这四个列表项添加鼠标移入移出事件,并通过input的点击事件添加列表项。

    <input type="button" name="" id="btn" value="添加" />
        <ul id="ul1">
            <li>111</li>
            <li>222</li>
            <li>333</li>
            <li>444</li>
        </ul>

    通常的写法是为每一个li添加移入移出事件,此时的问题是,新添加的li是没有事件的。

    window.onload = function(){
        var oBtn = document.getElementById("btn");
        var oUl = document.getElementById("ul1");
        var aLi = oUl.getElementsByTagName('li');
        var num = 4;
                
         //鼠标移入变红,移出变白
         for(var i=0; i<aLi.length;i++){
              aLi[i].onmouseover = function(){
                   this.style.background = 'red';
              };
              aLi[i].onmouseout = function(){
                   this.style.background = '#fff';
              }
          }
          //添加新节点
          oBtn.onclick = function(){
              num++;
              var oLi = document.createElement('li');
              oLi.innerHTML = 111*num;
              oUl.appendChild(oLi);
           };
     }

    此时我们可以将for循环用函数包裹起来,这样就可以解决新添加节点没有绑定事件的问题了。

    window.onload = function(){
         var oBtn = document.getElementById("btn");
         var oUl = document.getElementById("ul1");
         var aLi = oUl.getElementsByTagName('li');
         var num = 4;
                
         function mHover () {
             //鼠标移入变红,移出变白
             for(var i=0; i<aLi.length;i++){
                 aLi[i].onmouseover = function(){
                      this.style.background = 'red';
                 };
               aLi[i].onmouseout = function(){
                      this.style.background = '#fff';
               }
            }
        }
       mHover ();
       //添加新节点
      oBtn.onclick = function(){
           num++;
           var oLi = document.createElement('li');
           oLi.innerHTML = 111*num;
           oUl.appendChild(oLi);
           mHover ();
        };
    }

    现在,我们已经实现了最开始的目标了,但是,此时仅仅只是实现了功能,在性能优化上面,因为增加了DOM操作,导致浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,如果要用事件委托,就会将所有的操作放到js程序里面,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能。

    window.onload = function(){
         var oBtn = document.getElementById("btn");
         var oUl = document.getElementById("ul1");
         var aLi = oUl.getElementsByTagName('li');
         var num = 4;
                
         //事件委托,添加的子元素也有事件
         oUl.onmouseover = function(ev){
              var ev = ev || window.event;
              var target = ev.target || ev.srcElement;
              if(target.nodeName.toLowerCase() == 'li'){
                   target.style.background = "red";
              }
                    
          };
         oUl.onmouseout = function(ev){
             var ev = ev || window.event;
             var target = ev.target || ev.srcElement;
             if(target.nodeName.toLowerCase() == 'li'){
                 target.style.background = "#fff";
             }               
         };
                
         //添加新节点
         oBtn.onclick = function(){
              num++;
              var oLi = document.createElement('li');
              oLi.innerHTML = 111*num;
              oUl.appendChild(oLi);
         };
    }
  • 相关阅读:
    node 日志 log4js 错误日志记录
    使用sync 修饰符------子组件内部可以修改props
    rem是怎么计算的
    你真的了解word-wrap和word-break的区别吗? (转载)
    vue-router学习笔记
    vue学习笔记
    es6学习笔记
    vue中在页面渲染完之后获取元素(否则动态渲染的元素获取不到)
    flex布局居中无效果注意是否设置了宽度
    有关vuex的问题
  • 原文地址:https://www.cnblogs.com/yuyujuan/p/9260486.html
Copyright © 2011-2022 走看看