DOM事件流
概述
- 事件流是指
当给嵌套标签设置同样事件时它们之间的触发顺序
.w3c标准里有两套事件流:冒泡和捕获。 - 事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流
事件流的三个阶段
- 捕获阶段:由父标签到具体的子标签(由 DOM 最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程。)
- 完整捕获触发顺序:冒泡顺序的逆过程
- 事件目标阶段:(对真正用户发生交互的标签进行触发事件),事件目标就指的该标签
- 冒泡阶段:由子标签到具体的父标签(事件开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点的过程)
- 完整冒泡触发顺序是:
p->li->ul->body->html->document对象->window对象
- 完整冒泡触发顺序是:
小结
JS
代码中只能执行捕获或者冒泡其中的一个阶段onclick
只能得到冒泡阶段addEventListener(type,listener[,useCapture])
第三个参数如果是 true,表示在事件捕获阶段调用事件处理程序;如果是 false (不写默认就是false),表示在事件冒泡阶段调用事件处理程序有些事件是没有冒泡的,比如
onblur
、onfocus
、onmouseenter
、onmouseleave
事件对象(event)
概述
- 官方解释:event 对象代表事件的状态,比如键盘按键的状态、鼠标的位置、鼠标按钮的状态
- 简单理解:
- 事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面
- 这个对象就是事件对象
event
,它有很多属性和方法:比如- 谁绑定了这个事件,获取事件触发的元素
- 鼠标触发事件的话,会得到鼠标的相关信息,如鼠标位置
- 这个 event 是个形参,系统帮我们设定为事件对象,不需要传递实参过去
- 当我们注册事件时, event 对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)
eventTarget.onclick = function(event) {
// 这个 event 就是事件对象,常写成 e 或者 evt
}
eventTarget.addEventListener('click', function(event) {
// 这个 event 就是事件对象,常写成 e 或者 evt
})
事件对象常见的API
或属性
事件对象的属性方法 | 说明 |
---|---|
e.target |
表示事件目标本身,返回触发事件的对象 |
e.currentTarget |
当前冒泡的标签本身 |
e.preventDefault() |
阻止标签的默认行为,例如:不让a 标签跳转、表单提交(一般写在事件处理程序的第一行) |
e.stopPropagation() |
阻止进一步的冒泡或捕获 |
e.target
和this
的区别:
this
是事件绑定的元素, 这个函数的调用者(绑定这个事件的元素)e.target
是事件触发的元素。*e.target
指向我们点击的那个对象 谁触发了这个事件*
鼠标事件对象
鼠标事件对象 | 说明 |
---|---|
e.clientX &e.clientY |
鼠标相对于页面**首屏(视口)**的x和y坐标 |
e.pageX &e.pageY |
鼠标相对于整个页面文档的x和y坐标 |
e.offsetX &e.offsetY |
鼠标相对于触发事件标签的左上角的偏移量 |
键盘对象属性
键盘事件对象 属性 | 说明 |
---|---|
e.keyCode |
返回该键值的ASCll码值 |
keyCode
属性能区分大小写,返回不同的ASCII值
<body>
<script>
// 键盘事件对象中的keyCode属性可以得到相应键的ASCII码值
// 1. 我们的keyup 和keydown事件不区分字母大小写 a 和 A 得到的都是65
// 2. 我们的keypress 事件 区分字母大小写 a 97 和 A 得到的是65
document.addEventListener('keyup', function(e) {
console.log('up:' + e.keyCode);
// 我们可以利用keycode返回的ASCII码值来判断用户按下了那个键
if (e.keyCode === 65) {
alert('您按下的a键');
} else {
alert('您没有按下a键')
}
})
document.addEventListener('keypress', function(e) {
console.log('press:' + e.keyCode);
})
</script>
</body>
事件委托
- 事件委托也称事件代理,在
jQuery
中称为事件委派
概念
- 事件委托/事件代理指的是借助冒泡机制以及event对象来实现减少页面的事件处理程序代码的一种编程技巧。
原理
给父标签设置事件处理程序来代替给具体子标签设置,父标签会因为冒泡机制会执行代码。在事件处理程序中利用
e.target
来获取真正触发事件的子标签,判断并进行处理
步骤流程
- 给父标签设置事件处理程序
- 当触发事件时。在事件处理程序中通过
e.target
拿到具体触发事件的事件目标 - 通过事件目标的id或class来进行判断,执行对应的代码
html:
<ul class="nav">
<li class="myli">
<p class="myP">
<span>这是一个span标签</span>
<a href="#" class="link">百度一下</a>
<span>这是另一个span标签</span>
</p>
</li>
</ul>
javaScript:
//事件委托
document.body.addEventListener("click",function(e){
// 拿到事件目标
var elem = e.target;
//根据class或id来判断是具体哪个子标签,再来执行对应的代码
var classname = elem.getAttribute('class');
switch (classname) {
case "myP":
// 执行p标签被点击时的执行代码
console.log("p被点击了");
break;
case "myli":
console.log("li被点击了");
break;
case "link":
console.log("a被点击了");
break;
case "nav":
console.log("ul被点击了");
break;
}
})
好处优点
- 减少了事件处理程序的定义代码
- 统一管理子标签的事件处理程序
- 维护方便