事件
当在input
标签使用键盘输入时,就会产生键盘输入事件
当然,事件是存在多种类型: 鼠标事件、键盘事件、加载事件...
事件意味着用户或浏览器执行的某种动作。
事件作用
事件实现JS
和HTML
之间的交互,事件代表文档或浏览器窗口中某个有意义的时刻发生。
事件流
事件流描述了页面接收事件的顺序。
它的出现可以想象以下场景
<div id='1' >
<div id='2'>
<div id='3'>
</div>
</div>
<div>
当为三个 div
均绑定点击事件,点击 div3
的时候,是先触发到了 div1
还是 div3
的事件呢?
<!DOCTYPE html>
<html>
<head>
<title>Event Bubbling Example</title>
</head>
<body>
<div id="myDiv">Click Me</div>
</body>
</html>
事件冒泡
IE 事件流称为事件冒泡,认为点击后先触发了 div3
,在到 div2
, 最后为 div1
事件捕获
Netscape Communicator 团队认为点击后先触发了 div1
,在到 div2
, 最后为 div3
(大致猜想是因为 div1
包裹了 div2
,div2
又包裹了 div3
,想到达div3
需过前面的父节点,这大概也是使用capture
的原因)
DOM事件流(现代浏览器支持使用)
DOM2 Events 规范规定事件流分为 3 个阶段:事件捕获、到达目标和事件冒泡。事件捕获最先发生,为提前拦截事件提供准备,然后再到目标节点接受事件,最后冒泡事件。最晚需要在冒泡阶段响应对于的事件。
在 DOM 事件流中,实际的目标(<div>
元素)在捕获阶段不会接收到事件。这是因为捕获阶段从 document
到<html>
再到<body>
就结束了。下一阶段,即会在<div>
元素上触发事件的“到达目标”阶段,通常在事件处理时被认为是冒泡阶段的一部分(稍后讨论)。然后,冒泡阶段开始,事件反向传播至文档。
取消默认事件和事件流的中断
event.preventDefault()
由于部分元素自带有默认事件,比如链接标签,在单击时会跳转到的 href 属性指定的 URL
let link = document.getElementById("myLink");
link.onclick = function(event) {
event.preventDefault();
};
任何可以通过 preventDefault()取消默认行为的事件,其事件对象的 cancelable 属性都会设置为 true。
event.stopProgation()
stopPropagation()方法用于立即阻止事件流在 DOM 结构中传播,取消后续的事件捕获或冒泡。 例如,直接添加到按钮的事件处理程序中调用 stopPropagation(),可以阻止 document.body 上注册的事件处理程序执行。比如:
let btn = document.getElementById("myBtn");
btn.onclick = function(event) {
console.log("Clicked");
event.stopPropagation();
};
document.body.onclick = function(event) {
console.log("Body clicked");
};
如果这个例子中不调用stopPropagation(),那么点击按钮就会打印两条消息。但这里由于click事件不会传播到 document.body,因此 onclick 事件处理程序永远不会执行。所以使用 preventDefault() 应该要加入判断。
eventPhase,this、target 和 currentTarget 三者的关系。
注意 event 对象只在事件处理程序执行期间存在,一旦执行完毕,就会被销毁。
event.eventPhase 属性可用于确定事件流当前所处的阶段。如果事件处理程序在捕获阶段被调用,则eventPhase 等于 1;如果事件处理程序在目标上被调用,则 eventPhase 等于 2;如果事件处理程序在冒泡阶段被调用,则 eventPhase 等于 3。不过要注意的是,虽然“到达目标”是在冒泡阶段发生的,但其 eventPhase 仍然等于 2。
而当 eventPhase 等于 2 时,this、target 和 currentTarget 三者相等。