本文解析JavaScript中的事件源获取方法及DOM事件流机制。介绍如何通过target与srcElement兼容获取事件源,详解捕获、目标及冒泡三个阶段,并对比不同浏览器实现差异。同时说明stopPropagation与stopImmediatePropagation在阻止事件传播中的应用。
事件源
在事件处理过程中,触发当前操作的元素被称为事件源。例如,当用户点击网页中的 input 元素并触发 onclick 事件时,该 input 元素即为事件源。
常见事件源:
| (鼠标) 事件 | 描述 |
|---|---|
| onclick | 鼠标单击对象时触发 |
| ondblclick | 鼠标双击对象时触发 |
| onmousedown | 鼠标按钮被按下时触发 |
| onmousemove | 鼠标被移动时触发 |
| onmouseout | 鼠标离开监听该事件的元素或子元素时触发 |
| onmouseover | 鼠标移动到监听该事件的元素或子元素时触发 |
| onmouseup | 鼠标松开时触发 |
| (键盘) 事件 | 描述 |
|---|---|
| onkeydown | 键盘按下 |
| keypress | 键盘按住 |
| keyup | 键盘松开 |
| (表单控件) 事件 | 描述 |
|---|---|
| onblur | 失去焦点 |
| onfocus | 获取焦点 |
| oninput | 输入 |
| onchange | 改变 |
| onsubmit | 提交 |
| onreset | 重置 |
| (页面) 事件 | 描述 |
|---|---|
| onload | 页面加载结束 |
| onscroll | 滚动 |
| onresize | 改变大小 |
获取事件源
事件源作为 event 对象的属性存在。依据 W3C 规范,该属性为 target;然而,IE8.0 及以下版本不支持此属性,需使用 srcElement 属性来获取事件源。
<html>
<head>
<title>获取事件源</title>
</head>
<body>
<div id="demo">点击这里</div>
<script type="text/javascript">
document.getElementById("demo").onclick=function(e){
var eve = e || window.event;
var srcNode = eve.target || eve.srcElement; // 兼容所有浏览器
alert(srcNode);
}
</script>
</body>
</html>事件流:
事件流描述了页面接收事件的顺序,也可理解为事件在文档树中传播的顺序。
DOM事件流存在的三个阶段:
- 事件捕获阶段
- 处于目标阶段
- 事件冒泡阶段
事件捕获(event capturing):当鼠标点击或触发 DOM 事件时,浏览器会从根节点开始由外向内传播事件。若父元素通过事件捕获方式注册了相应事件,点击子元素时会先触发父元素绑定的事件。
事件冒泡(dubbed bubbling):与事件捕获相反,事件冒泡的顺序是由内向外传播,直至到达根节点。
DOM 标准事件流的触发顺序为:先捕获后冒泡。即触发 DOM 事件时,先进行事件捕获,捕获到事件源后,再通过事件传播机制进行事件冒泡。
不同浏览器对此有不同实现。IE10 及以下版本不支持捕获型事件,因此缺少事件捕获阶段;而 IE11、Chrome、Firefox、Safari 等浏览器则同时支持这两个阶段。
target 和 currentTarget
- target 是触发事件的具体对象,仅出现在事件机制的目标阶段,即“谁触发了事件,谁就是 target”。
- currentTarget 是绑定了当前事件类型的对象,它可能是目标节点的祖先节点。
阻止事件在冒泡阶段传播
event.stopPropagation //阻止事件在冒泡阶段传播
<!-- 例子结构 -->
<div id="outer">
<p id="inner"></p>
</div>/**
* 点击#inner之后会发生如下过程:
* outer捕获阶段
* inner 一
* inner 二
* inner 三
*/
const inner = document.querySelector('#inner');
const outer = document.querySelector('#outer');
inner.addEventListener("click", event => {
console.log("inner 一");
}, false);
inner.addEventListener("click", event => {
console.log("inner 二");
event.stopPropagation();
}, false);
inner.addEventListener("click",event => {
console.log("inner 三");
}, false);
outer.addEventListener("click", event => {
console.log("outer捕获阶段");
}, false);
outer.addEventListener("click", event => {
console.log("outer冒泡阶段");
}, false);若多个相同类型的事件监听函数绑定到同一元素,当该类型事件触发时,它们将按添加顺序执行。若其中某个监听函数执行了event.stopImmediatePropagation()方法,则当前元素剩余的监听函数将不再执行,并阻止事件在冒泡阶段继续传播。
/**
* 点击#inner之后会发生如下过程:
* outer捕获阶段
* inner 一
* inner 二
*/
const inner = document.querySelector('#inner');
const outer = document.querySelector('#outer');
inner.addEventListener("click", (event) => {
console.log("inner 一");
}, false);
inner.addEventListener("click", (event) => {
console.log("inner 二");
event.stopImmediatePropagation();
}, false);
inner.addEventListener("click",(event) => {
console.log("inner 三");
}, false);
outer.addEventListener("click", event => {
console.log("outer捕获阶段");
}, false);
outer.addEventListener("click", event => {
console.log("outer冒泡阶段");
}, false);以上就是JavaScript常见事件源与事件流的获取方法及解析的详细内容,更多关于JavaScript事件源事件流的资料请关注本站其它相关文章!