事件冒泡、事件捕获和事件委托
浅淡事件冒泡、事件捕获和事件委托
先来说下事件冒泡和事件捕获的机制由来。
事件冒泡和事件捕获分别由微软和网景公司提出,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题,后来由W3C决定这两个事件都存在,事件流触发顺序是先触发事件捕获,然后再决定触发冒泡(再决定的意思的可以阻止事件冒泡),我理解的意思冒泡就是从一个泡泡从水底慢慢到水面的过程,捕获是冒泡的倒叙。
下面用代码来演示下过程分别是grandpa father son 三个层级元素
<style> div{ display: flex; justify-content: center; align-items: center; } .grandpa{ background: #b15959; width: 200px; height: 200px; border-radius: 50%; } .father{ background: green; width: 150px; height: 150px; border-radius: 50%; } .son{ background: lightgreen; width: 100px; height: 100px; border-radius: 50%; } </style> <div class="grandpa"> <div class="father"> <div class="son"></div> </div> </div>
1事件冒泡(IE的微软提出来的事件流)
就是当我触发一个事件的时候,事件会从最内层的元素开始发生,一直向上传播,直到document对象。当我们点击了son,触发顺序是son > father > grandpa >document
<script> const son = document.querySelector('.son') const father = document.querySelector('.father') const grandpa = document.querySelector('.grandpa') son.addEventListener('click',clickDeal) father.addEventListener('click',clickDeal) grandpa.addEventListener('click',clickDeal) function clickDeal(e){ console.log(this) } </script>
我能通多监听每个div的点击事件这个监听是以事件冒泡进行监听的
点击之后依次出现的是 son > father >grandpa
element.addEventListener(event, function, useCapture)
addEventListener方法用来为一个特定的元素绑定一个事件处理函数,是JavaScript中的常用方法,其传入三个参数,分别是‘没有on的事件类型’,‘事件处理函数’,‘控制事件阶段’,第三个参数是boolean类型,默认是false,表示在事件冒泡的阶段调用事件处理函数,像上图中传入true,就表示在事件捕获的阶段调用事件处理函数。
2事件捕获(网景提出来的事件流)
与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素。当一个元素触发事件后会先从document开始捕获,只但触发这个事件流的具体元素 document > groundpa >father > son
<script> const son = document.querySelector('.son') const father = document.querySelector('.father') const grandpa = document.querySelector('.grandpa') son.addEventListener('click',clickDeal,true) father.addEventListener('click',clickDeal,true) grandpa.addEventListener('click',clickDeal,true) function clickDeal(e){ console.log(this) } </script>
修改它事件流为捕获触发顺序即grandpa >father >son
3事件委托(事件代理)
事件代理(Event Delegation),又称之为事件委托。是JavaScript中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown......)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。
实现方式:通过给父节点添加监听
优点:
1.大量减少内存占用,减少事件注册。
2.新增元素实现动态绑定事件
需求给li添加点击事件
没有使用事件代理
<div> <ul> <li>第一项</li> <li>第二项</li> <li>第三项</li> </ul> </div> <script> const liArray = document.querySelectorAll('li') //给 liArray.forEach(item=>{ item.addEventListener('click',function(){ console.log(this)},false) }) </script>
需要给每个li添加监听事件,
下面使用事件代理
<div> <ul> <li>第一项</li> <li>第二项</li> <li>第三项</li> </ul> </div> <script> const ul = document.querySelector('ul') ul.addEventListener('click',function(){ //获取对应的元素进项操作 },false) </script>