什么是合成事件
在我们React的事件处理函数当中,我们打印出的event对象是一个SyntheticEvent,与原生的事件不同。我们常常是通过event.nativeEvent来获取我们的原生事件对象。
为什么会出现合成事件
1、进行浏览器的兼容
回顾我们的原生事件
1.DOM0事件
button.onclick=handlerOnclick;
<button onclick="handlerOnclick()">点击</button>
DOM0中,相同的事件监听函数只能绑定一个,后面注册的事件监听函数会被覆盖
2.DOM2事件
DOM2中,相同的事件监听函数可以绑定多个。
DOM2的代码如下:
button.addEventListenr('click',handleOnclick,true);//事件绑定函数
button.removeEventListener('click',handlerOnclick,true);
但是DOM2事件不能兼容IE6~8的浏览器。
DOM2的事件模型中,一次事件一共有三个过程:
(1)、事件捕获阶段:事件从document一直向下传播到目标元素,依次检查经过的节点是否有绑定事件监听函数,有则执行。
(2)、事件处理阶段:事件到达目标元素,触发目标元素绑定的事件处理函数。
(3)、事件冒泡阶段:事件从目标元素一直冒泡到document,冒泡的过程中依次检查经过的元素是否有绑定事件处理函数,有则执行。
具体的代码和运行结果如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
display: flex;
justify-content: center;
align-items: center;
}
#grand{
width:300px;
height:300px;
background-color: aqua;
display: flex;
justify-content: center;
align-items: center;
}
#father{
width:200px;
height:200px;
background-color: blueviolet;
display: flex;
justify-content: center;
align-items: center;
}
#son{
width:100px;
height:100px;
background-color: rgb(231, 135, 18);
}
</style>
</head>
<body>
<div id="grand">
<div id="father">
<div id="son"></div>
</div>
</div>
</body>
<script>
let grand=document.getElementById("grand");
let father=document.getElementById("father");
let son=document.getElementById("son");
grand.addEventListener('click',()=>{
console.log("祖先元素事件捕获");
},true);
grand.addEventListener('click',()=>{
console.log("祖先元素事件冒泡");
});
father.addEventListener('click',()=>{
console.log("父元素事件捕获");
},true);
father.addEventListener('click',()=>{
console.log("父元素事件冒泡");
});
son.addEventListener('click',()=>{
console.log("子元素事件捕获");
},true);
son.addEventListener('click',()=>{
console.log("子元素事件冒泡");
});
</script>
</html>
执行的结果:
点击子元素:
3、IE事件模型
IE事件模型的事件流:
(1)、事件处理阶段:事件在子元素时触发事件监听函数
(2)、事件冒泡阶段:冒泡到document,依次触发经过的节点多的事件处理函数。
具体的事件绑定的代码:
button.attachEvent('click',handlerOnclick);
button.detachEvent('click',handlerOnclick);
React中的事件要进行跨浏览器的兼容,保证冒泡的一致性,为了解决这个问题,引入了冒泡事件。
2、避免垃圾回收
在我们原生的事件中,我们会为每个按钮绑定一个事件处理的函数,当事件的触发,我们会频繁地创建和销毁。针对这一个情况,React引入一个事件池。当我们销毁事件时,我们并不会真正的销毁,当下次触发事件时,从事件池中获取事件对象。
3、方便事件统一管理和事务机制
React合成事件具有和普通的事件对象相同的接口,可以进行冒泡和阻止默认的行为。
本章节主要讲解了什么是合成事件,为什么需要合成事件以及回顾了原生的DOM事件,后面的章节将会介绍合成事件的原理