终于搞懂DOM事件!

导读

  1. DOM事件绑定的几种方式javascript

    • DOM元素上面绑定
    • js代码匿名绑定
    • IE事件监听绑定:attachEvent / detachEvent
    • 事件监听绑定:addEventListener / removeEventListener
    • 兼容IE的事件监听
  2. 事件流html

    • 事件流分为哪几个阶段?
    • DOM事件流的发展
  3. 事件委托java

    • 什么是事件委托
    • 事件委托的好处
    • jquery中的事件委托
    • 如何实现事件委托
  4. target 与 currentTarget的区别是什么?node

🐑 DOM事件绑定的几种方式

1.DOM元素上面绑定

<button onclick="btnClick1()" onclick="btnClick2()">click me</button>

<script> function btnClick1(){console.log('click!1')} function btnClick2(){console.log('click!2')} </script>
复制代码

若是绑定了同一元素绑定了多个onclick 事件,那么只会执行第一个。jquery

2.js代码匿名绑定

btn.onclick = function(){console.log('1')}
btn.onclick = function(){console.log('2')}
复制代码

若是是在js里面匿名绑定的,那么只会执行最后一个。chrome

3.IE事件监听绑定:attachEvent / detachEvent

btn.attachEvent('onclick', function(){})
复制代码

1.事件名,带有onui

2.若是同一元素绑定了多个click 事件,都会执行,而且有前后顺序。spa

3.注意:这个方法,chrome不支持,只有IE支持code

4.绑定了事件记得取消绑定,避免内存泄漏cdn

4.事件监听绑定:addEventListener / removeEventListener

btn.addEventListener('click',function(){}, false) // 能够区分捕获阶段 和 冒泡阶段
复制代码

1.事件名不带on

2.若是绑定了同一元素绑定了多个click 事件,都会执行,而且有前后顺序。

3.而且第三个参数的意思是是否开启/使用事件捕获阶段,默认是false,就是默认是冒泡阶段。

4.绑定了事件记得取消绑定,避免内存泄漏

5.兼容IE的事件监听

if (a.addEventListener) {
	a.addEventListener('click', function(){
      console.log('is addEventListener!') 
    })
  
} else if (a.attachEvent) {
	a.attachEvent('onclick', function(){
      console.log('is attachEvent!') 
    })
  
} else {
	console.log('others')
}

复制代码

🐑 事件流?

事件流分为哪几个阶段?

1.捕获阶段:从上往下,document会先捕获到,到html,body,...,直到触发事件的那个元素

2.目标阶段:触发事件的那个元素

3.冒泡阶段:从下往上,触发事件的那个元素往父元素,...,到body,html,document

DOM事件流的发展

其实刚开始DOM0的时候是只有目标阶段 和 冒泡阶段的,直到出现了DOM2,才引进了捕获阶段。

1.DOM0

DOM0事件流只有两个阶段:目标阶段 + 冒泡阶段

btn.onclick = function(){

}
复制代码

2.DOM2(IE不支持)

DOM2事件流只有3个阶段:捕获阶段 + 目标阶段 + 冒泡阶段

那么DOM2里面如何区分捕获阶段和冒泡阶段?

addEventListener 第二个参数的意思是,是否开启事件捕获。能够区分,true 事件捕获,默认是false 事件冒泡。

btn.addEventListener('click',function(){

}, true) // true 事件捕获

btn.removeEvenetListener('click',function(){

}, false) // false 事件冒泡(默认)

复制代码

🐑事件委托

什么是事件委托

事件委托是,把本身元素的响应事件委托到其余元素上面。通常是委托再父元素上。

事件委托的好处

1.减小内存的消耗

若是是一个列表,咱们给每一个列表项都绑定一样的事件,是很是消耗内存的。

咱们能够绑定到父组件列表上面,这样能够减小内存的消耗;

2.减小重复工做

咱们的列表项,若是删除增长,都要重复进行一个操做就是删除事件和绑定事件。

若是咱们绑定在父组件上面,咱们就能够不用作这些重复的工做了。

jquery中的事件委托

on/delegate

如何实现事件委托

事件委托通常是由 事件冒泡来实现的

案例🌰:使用addEventListener点击li弹出内容,而且动态添加li以后有效

<ul id="list">
	<li>1</li>
	<li>2</li>
	<li>3</li>
	<li>4</li>
</ul>
复制代码
// 给父层元素绑定事件
document.getElementById('list').addEventListener('click', function (e) {
  var target = event.target
  if (target.nodeName.toLocaleLowerCase === 'li') {
    console.log('the content is: ', target.innerHTML);
  }
});
复制代码

🐑 target 与 currentTarget的区别是什么?

target指的是目标阶段。

currentTarget指的是捕获阶段,目标阶段 和 冒泡阶段。(通常指目标元素的父级)

<div id="c">c
    <div id="b">b
    	<div id="a">a</div>
  </div>
</div>
复制代码
const b = document.getElementById('b');
const a = document.getElementById('a');
const c = document.getElementById('c');

b.addEventListener('click', (e)=>{
  console.log("click b=>", "target:",e.target, "currentTarget:",e.currentTarget)
})
//b.addEventListener('click', (e)=>{
// console.log("click b=>", "target:",e.target, "currentTarget:",e.currentTarget)
//},true) //捕获阶段

a.addEventListener('click',(e)=>{
  console.log("click a=>", "target:",e.target, "currentTarget:",e.currentTarget)
})
//a.addEventListener('click',(e)=>{
// console.log("click a=>", "target:",e.target, "currentTarget:",e.currentTarget)
//},true) //捕获阶段

c.addEventListener('click',(e)=>{
  console.log("click c=>", "target:",e.target, "currentTarget:",e.currentTarget)
})
//c.addEventListener('click',(e)=>{
// console.log("click c=>", "target:",e.target, "currentTarget:",e.currentTarget)
//},true)//捕获阶段

复制代码

1.当点击c模块的时候

捕获阶段:c(currentTarget)

目标阶段:c (target)

冒泡阶段:c(currentTarget)

2.当点击b模块的时候

捕获阶段:c

通过c模块,触发了c模块的click事件,因此c模块的currentTarget是c模块,可是target仍是b模块

目标阶段:b

对于b模块本身来讲,target 和 currentTarget都是本身

冒泡阶段:c

通过c模块,触发了c模块的click事件,因此c模块的currentTarget是c模块,可是target仍是b模块

点击b模块.jpg

3.当点击a模块的时候

捕获阶段:c -- b

通过了c模块和b模块,因此触发了c,b模块的点击事件。对于c模块来讲,currentTarget就是c模块,target仍是a模块。对于b模块来讲,currentTarget就是b模块,target仍是a模块。

目标阶段:a

对于a模块本身来讲,target 和 currentTarget都是本身

冒泡阶段:b --- c

通过了c模块和b模块,因此触发了c,b模块的点击事件。对于c模块来讲,currentTarget就是c模块,target仍是a模块。对于b模块来讲,currentTarget就是b模块,target仍是a模块。

最后

相关文章
相关标签/搜索