码迷,mamicode.com
首页 > Web开发 > 详细

js中的事件委托

时间:2020-03-10 11:56:12      阅读:55      评论:0      收藏:0      [点我收藏+]

标签:nts   lower   管理   ||   nod   处理   解决办法   ase   on()   

事件委托,顾名思义,就是将本来需要 A 处理的事情,委托给 B 来处理。在 JavaScript 中的事件委托又称事件代理,事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。当然,如果子元素阻止了事件冒泡,那么委托也就没法实现了。

如何举个例子形容呢:
有三个同事预计会在周一收到快递。为签收快递,有两种办法:一是三个人在公司门口等快递;二是委托给前台 MM 代为签收。现实当中,我们大都采用委托的方案(公司也不会容忍那么多员工站在门口就为了等快递)。前台 MM 收到快递后,她会判断收件人是谁,然后按照收件人的要求签收,甚至代为付款。这种方案还有一个优势,那就是即使公司里来了新员工(不管多少),前台 MM 也会在收到寄给新员工的快递后核实并代为签收。

这里其实还有 2 层意思的:

第一,现在委托前台的同事是可以代为签收的,即程序中的现有的 dom 节点是有事件的;

第二,新员工也是可以被前台 MM 代为签收的,即程序中新添加的 dom 节点也是有事件的。

下面我们举一个代码例子:

我们要实现一个需求,当鼠标悬浮在 li 元素上,li 元素背景变成红色,离开时,去掉背景。代码如下:

<ul id="ul">
  <li>a</li>
  <li>b</li>
  <li>c</li>
</ul>
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 元素,并为之加上 mouserover 和 mouseout 事件。这只适用于 li 元素特别少的情况,如果 li 元素特别多,定会引起性能问题。还有一个问题,如果这时候动态添加了一个 li 元素,这个元素是没法响应事件的,因为没有给他绑定任何事件。

通过事件委托实现

window.onload=function(){
    var oUl = document.getElementById('ul');
    oUl.onmouseover = function(e){
        var e = e || window.event;
        var target = e.target || e.srcElement;
        if(target.nodeName.toLowerCase() == "li"){
        target.style.background = "red";
        }
    }
    oUl.onmouseout = function(e){
        var e = e || window.event;
        var target = e.target || e.srcElement;
        if(target.nodeName.toLowerCase() == "li"){
        target.style.background = "";
        }
    }
}
}

在这段代码中,通过 event.target 来实现事件委托。这种方法避免了循环,提高了性能。

标准浏览器用 event.target,IE 浏览器用 event.srcElement

新问题,如果 li 还包含了其他元素怎么办呢,这样 target 就不是 li 了。
解决办法:

var oUl = document.getElementById('test');
oUl.addEventListener('click', function(ev) {
  var target = ev.target;
  while (target !== oUl) {
    if (target.tagName.toLowerCase() == 'li') {
      console.log('li click~');
      break;
    }
    target = target.parentNode;
  }
});

另外一个例子:

<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('选择');
  };
};

使用事件委托:

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;
      }
    }
  };
};

js中的事件委托

标签:nts   lower   管理   ||   nod   处理   解决办法   ase   on()   

原文地址:https://www.cnblogs.com/vipUser/p/12454452.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!