美文网首页
使用原生 JS 实现事件委托举例

使用原生 JS 实现事件委托举例

作者: 七里之境 | 来源:发表于2017-04-18 15:42 被阅读0次

DOM事件

在我们的日常的生活中,无时无刻不在发生着各种类型的事件。比如说体育赛事、娱乐新闻、战争甚至天气变化等等都可以被称为事件。这些事件有三个共同的特点:监听变化通知
转到代码上,当用户使用一个程序时,代码会监听用户的行为,而用户行为发生变化时,代码会得到通知,继而做出反应,这就是发生在代码上的事件。而DOM事件就是在DOM节点上发生的事件,通常我们会为DOM元素注册事件处理函数,来监听DOM事件。
DOM事件可以分为以下两类:

  1. level 0事件
button.onclick = function(e){alert('Hello world!')}// or:
<button onclick="alert('Hello world!')">

level 0事件是在W3C认证前的事件,可以通过如上两种方式进行监听。这种事件的特点是:每个元素和事件只能设置一个事件处理函数,先设置的会被后设置的覆盖。

  1. level 2事件
button.addEventListener('click', function(e){alert('Hello world')});

level 2事件是经过W3C认证的事件,它将事件的传播方式分为了三个阶段:捕获阶段(Capturing Phase)、目标阶段(Target Phase)和冒泡阶段(Bubble Phase)。
下图是W3C对DOM事件派发过程的图解。


DOM事件流在DOM树中派发事件

level 2事件通过EventTarget.addEventListener() 方法将指定的监听器注册到EventTarget上,当该对象触发指定的事件时,指定的回调函数就会被执行。该方法允许给一个事件注册多个 listener。

事件委托

在了解什么是DOM事件以及给DOM事件绑定监听器的几种方法后,我们来谈谈事件委托。

  1. e.targete.currentTarget
    当我们给目标元素target绑定一个事件监听器target.addEventListener(event, function(e){}),并指定回调函数function(e),函数的参数e表示事件。此时,e.target与e.currentTarget分别表示直接触发事件的元素与被监听的元素。
    举个栗子:
<html>
<body>
<ul style='list-style:none;max-width:200px;border:1px solid;'>
  <li>点我试试</li>
<ul>
<script>
  (document.querySelector('ul')).addEventListener('click' ,function(e){
    console.log('e.target')
    console.log(e.target)
    console.log('e.currentTarget')
    console.log(e.currentTarget)
  })
  </script>
</body>
</html>

这段代码为一个ul元素绑定了一个监听器,当ul上发生点击事件时,分别输出e.target和e.currentTarget的值。
当点击ul中的li元素时,该段代码的在控制台输出的结果如下:


此时,e.target为直接点击的元素li,而e.currentTarget为被监听的元素ul。由此我们可以得到一个启发,触发事件的元素与被监听的元素不一定是一个元素。于是就来到了本文的重点内容——事件委托。
  1. 如何进行事件委托
    什么情况下会用到事件委托呢?举两个例子。
    (1) 当存在多个元素可以共用同一个监听器。
<html>
<body>
<ul>
  <li>点<span>这里</span></li>
  <li>点这里</li>
</ul>
<style>
  ul, li{
  list-style:none;
  border:1px solid;
  padding:10px;
  background:#ddd
}
li{
  text-align:center;
  margin:10px;
  background:#fff
}
</style>
</body>
</html>

上面的代码中定义了如图所示的一个ul,它包裹着两个li,第一个li中还有一个子元素span。如果我们希望点击两个li均执行同一条命令时,第一种方法是为每个li都绑定一个监听器,但当li很多时,这样处理就过于繁琐。
这时我们会想到可以直接监听ul,为ul绑定事件函数,那么只要li存在于ul的内部,点击任意的一个li都会执行这条命令。但同样存在一个问题,当点击li的外部,也就是图中的灰色区域时,命令同样会被执行。
那么如何仅仅在点击li的覆盖区域的时候才执行这段命令呢,可以用以下这段代码。

var ul=document.querySelector('ul')
ul.addEventListener('click',function(e){
  var el = e.target
//判断当前点击的元素是否为li,如果不是,执行以下的while循环
  while(el.tagName !== 'LI'){
//如果点击的元素为ul,直接跳出循环
    if(el === ul){
      el = null
      break;
    }
//否则,将当前元素父元素赋给el
      el=el.parentNode
  }
//如果最后el不为null,则打出'ok'
  if(el){
    console.log('ok')
  }
//否则,打出'你点击的不是li'
  else console.log('你点击的不是li')
})

这段代码实现了当点击的区域在li范围内时,不管点击的是li元素本身,还是li的子元素span,都会执行console.log('ok'),但当点击区域超出li的范围,则执行' console.log('你点击的不是li')'。这就成功实现了一个事件委托。
(2) 用事件委托实现动态监控
还有一种情况,也会用到事件委托,那就是需要动态监控的时候。
看以下代码:

<html>
<body>
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
</ul>
  <button id=addButton>+</button>
</body>
</html>
<style>
li{
  border: 1px solid;
}
</style>
<script>
addButton.onclick = function(){
  var li = document.createElement('li')
  li.textContent = 'new' 
  document.querySelector('ul').appendChild(li)
}
document.querySelector('ul').onclick = function(e){
  console.log(e.target)
}
</script>
</body>
</html>

这段代码实现的效果如下:

当点击左下角的加号按钮时,会增加一个新的li,同时在点击li时,在控制台输出被点击的li的内容。这就是用事件委托实现动态监控。

小结

本文介绍了两种用原生JS实现事件委托的方法,在不同的情境与需求下,这些方法可以做不同程度的优化,需要结合实例展开分析。

相关文章

  • 使用原生 JS 实现事件委托举例

    DOM事件 在我们的日常的生活中,无时无刻不在发生着各种类型的事件。比如说体育赛事、娱乐新闻、战争甚至天气变化等等...

  • 使用原生 JS 实现事件委托

    1. 事件是什么 DOM事件即为Event对象。Event对象代表事件的状态,比如事件在其中发生的元素、键盘按键的...

  • 使用原生JS 实现事件委托

    JavaScript事件代理 事件绑定 要想让 JavaScript 对用户的操作作出响应,首先要对 DOM 元素...

  • 使用原生 JS 实现事件委托

    JavaScript与HTML之间的交互是通过事件实现的。在学习事件委托之前,我们需要先了解事件含义、事件绑定、事...

  • 使用原生JS实现事件委托

    什么是事件 事件(event),定义为:比较重大,对一定的人群会产生一定影响的事情。对于前端开发来说,事件就是在浏...

  • 使用原生 JS 实现事件委托

    很多情况下都可能使用到事件委托,那么对于一个使用者来说,为什么要使用事件委托?又是否正确的使用了事件委托?这里我想...

  • 使用原生 JS 实现事件委托

    很多人是在使用事件委托的,那对于一个使用者来说,只要能正确的使用好事件委托,完成工作,就算可以了,那么你有认真的考...

  • 使用原生JS实现事件委托

    事件委托(Event Delegation)是JS中一项十分重要的应用,使用事件委托可以避免对每一个节点添加监听器...

  • 使用原生 JS 实现事件委托

    1、如何监听事件 目前W3C对DOM进行标准化规定中对事件监听有两种方式,DOM level 0 中规定 butt...

  • 使用原生JS实现事件委托

    为什么要用事件委托? 首先,需要了解一下常用的事件监听方法有哪些区别: 常用的监听方法的区别 通常,在页面中监听事...

网友评论

      本文标题:使用原生 JS 实现事件委托举例

      本文链接:https://www.haomeiwen.com/subject/ifeaattx.html