前言
下面三段代码都是响应鼠标点击事件。
JS原生事件
DOM0级:
document.getElementById("test").onclick = doSomething();
DOM2级:
const btn = document.querySelector('button');
function bgChange() {
const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
document.body.style.backgroundColor = rndCol;
}
btn.addEventListener('click', bgChange);
React合成事件
function Button({onClick, children}){
return (
<button onClick = {onClick}>
{children}
</button>
)
}
function PlayerButton({movieName}){
funtion handlePlayClick(){
console.log(`play ${movieName}!`);
}
return (
<Button onClick = {handlePlayClick}>
Play "{movieName}"
</Button>
)
}
function UploadButton(){
return (
<Button onClick={()=>{console.log(`Uploading!`)}}>
Upload Image
</Button>
)
}
export default function Toolbar() {
return (
<div>
<PlayerButton movieName="Rainy Day" />
<UploadButton />
</div>
)
}
原生事件
常见的原生事件采用DOM2级,给浏览器提供了一个函数addEventListener()
:
element.addEventListener(event, function, useCapture)
:
参数 | 描述 |
---|---|
event | 字符串,指定事件名 |
function | 事件触发时执行的函数 |
useCapture | 指定事件是否在捕获或冒泡阶段执行 |
该方法将指定的监听器注册到EventTarget
上,当该对象触发指定的事件时,指定的回调函数就会执行。还有一个相对应的方法removeEventListener()
移除事件监听器。
event
事件名API:https://developer.mozilla.org/zh-CN/docs/Web/API/Element#%E4%BA%8B%E4%BB%B6
在DOM2级模型中,一次事件的发生包含三个过程:事件捕获阶段、处于目标阶段和事件冒泡阶段
-
事件捕获: 事件对象通过目标节点的祖先
Windows
传播到目标的父结点。当某个元素触发某个事件(如onclick
),顶层对象document
就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。 -
处于目标; 事件对象到达事件目标节点,如果阻止事件冒泡,那么该事件对象将在此阶段完成后停止传播。
使用
stopPropagation
阻止事件在冒泡链上进一步扩大:video.onclick = function(e) { e.stopPropagation(); video.play(); }
-
事件冒泡: 事件对象以相反的顺序从目标节点的父项开始传播,从目标节点的父项开始到Window结束。途中如果有节点绑定了相应的事件处理函数,这些函数会触发一次。
React合成事件
React元素的事件处理和DOM元素相似,语法略有不同:
- React事件的命名采用小驼峰式(camelCase),而不是纯小写。
- 使用JSX语法时需要传入一个函数作为事件处理函数,而不是一个字符串。
传统HTML:
<button onclick="activateLasers()">
Activate Lasers
</button>
React中:
<button onClick={activateLasers}>
Activate Lasers
</button>
React绑定事件有自己的一套机制,React并不是将事件直接绑定到dom上,而是采用事件冒泡的形式冒泡到document
上面,然后将React事件封装给正式的函数运行处理。
React的事件注册过程主要做了两件事:document
上注册,存储事件回调。
- 在
docuement
上注册事件register
:
addEventListener-click
addEventListener-change
在React组件挂载阶段,根据组件内的声明的事件类型(onclick
,onchange
)等,在document
上注册事件,并指定统一的回调函数dispatchEvent
。 - 存储事件回调
listener
{
click: { key1: fn, key2: fn }
change: { key1: fn, key2: fn }
}
React为了在触发事件时可以找到对应的回调去执行,会把组件内的所有事件统一存储在一个对象中。