Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[js] 第52天 什么是事件委托?它有什么好处?能简单的写一个例子吗? #204

Open
haizhilin2013 opened this issue Jun 6, 2019 · 6 comments
Labels
js JavaScript

Comments

@haizhilin2013
Copy link
Collaborator

第52天 什么是事件委托?它有什么好处?能简单的写一个例子吗?

@haizhilin2013 haizhilin2013 added the js JavaScript label Jun 6, 2019
@rocky-191
Copy link

一个ul列表,将本来在每一个li上的事件写在ul上面,避免多个绑定,这种就是事件委托。当li个数很多的时候可以显著减少事件的绑定,另外一种情况就是动态添加li后,使用事件委托的方式事件依然可以正常触发使用,如果绑定到li上就会无效或者需要重新绑定了

@myprelude
Copy link

首先从时间冒泡来说起,DOM2级事件,规定事件过程如下

                     顶层(document)
                         ||   捕获           ||
                         ||                     ||  冒泡 
                     事件触发源 = = =

当我们页面有一个按钮触发点击事件,首先从页面的顶层的document开始,一层层向下捕获直到事件抵达该按钮,触发对应点击事件;然后改点击事件又会从按钮开始向上传递直到顶层document(类似于冒泡所以叫冒泡)。
这里讲的事件代理就是在事件冒泡时去做的。我们将事件代理到docement上,页面的button触发点击事件,会冒泡到document上,document在判断事件的target来判断事件执行的目标,来执行对应的事件。
案列:
react 事件机制

@qingleizhang123
Copy link

qingleizhang123 commented Jun 24, 2019

事件委托

即利用事件冒泡机制处理指定一个事件处理程序,来管理某一类型的所有事件

事件委托的作用

  1. 利用冒泡的原理,将事件加到父级身上,触发执行效果,这样只在内存中开辟一块空间,既节省资源又减少DOM操作,提高性能
  2. 可以为动态添加的元素绑定事件

js实现事件委托的三大步骤:

第一步:给父元素绑定事件

给元素ul添加绑定事件,通过addEventListener为父元素绑定事件

第二步:监听子元素的冒泡事件

这里默认是冒泡,点击子元素li会向上冒泡

第三步:找到是哪个子元素的事件

通过匿名回调函数的参数e用来接收事件对象,通过target获取触发事件的目标

案例:ul中触发每个li来改变他们的背景颜色

<ul id='ul'>
    <li>111111</li>
    <li>222222</li>
    <li>333333</li>
</ul>
<button id='button'>添加元素</button>
window.onload = function(){
  let oUl = document.getElementById('ul');
  let aLi = oUl.getElementsByTagName('li');
  let but = document.getElementById('button');
  let now = 3;
  // 事件源:event对象,不管在哪个事件中,只要你操作的哪个元素就是事件源
  // ie:window.event.srcElement
  // 标准:event.target
  oUl.onmouseover = function(e){
      let ev = e || window.event;
      let target = ev.target || ev.srcElement;
      if(target.nodeName.toLowerCase() == 'li'){
          target.style.background = 'red';
      }
  }
  oUl.onmouseout = function(e){
      let ev = e || window.event;
      let target = ev.target || ev.srcElement;
      if(target.nodeName.toLowerCase() == 'li'){
          target.style.background = '';
      }
  }
  but.onclick = function(){
      now ++;
      let newLi = document.createElement('li');
          newLi.innerHTML = 111111 * now;
          oUl.appendChild(newLi);
  }
}

@Alex-Li2018
Copy link

假设一个根元素下面有1000个子元素,那么给这1000个子元素全部绑定点击事件,那么就会有1000个点击事件,利用事件的冒泡只给根元素绑定点击事件,这样只需要监听子元素的点击冒泡,进行对应的操作.可以节省很大一部分内存开销

@MrZ2019
Copy link

MrZ2019 commented Nov 23, 2020

一个ul列表,将本来在每一个li上的事件写在ul上面,避免多个绑定,这种就是事件委托。当li个数很多的时候可以显著减少事件的绑定,另外一种情况就是动态添加li后,使用事件委托的方式事件依然可以正常触发使用,如果绑定到li上就会无效或者需要重新绑定了

@xiaoqiangz
Copy link

事件委托是利用事件的冒泡机制,给父组件添加事件,避免子组件反复绑定事件。 相应性能也可以得到很好的提升。

  • 111
  • 333
  • 444
  • 555
  • 666
  • 777
  • 888
新增 <script> var but = document.querySelector('button') var ul = document.querySelector('ul') but.addEventListener('click', function(e) { var li = document.createElement('li') li.innerText = ul.children.length + 1 + '---add' ul.appendChild(li) }, false) ul.addEventListener('click', function(e) { if (e.target.nodeName == 'LI') { console.log(e.target.innerText) } }) </script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
js JavaScript
Projects
None yet
Development

No branches or pull requests

7 participants