基本概念
有事件作用于节点时,有两种类型
- 冒泡流【IE提出】: 由具体元素向外(上) 传递事件
- 捕获【网景提出】: 由最外层元素向具体元素向内(下) 传递事件 w3c 同时兼容两种事件流,早期IE浏览器只有冒泡;
理论上,在绑定的一个事件里,只会发生其中一个事件流;但浏览器在执行过程中,不按照该理论执行;
DOM0 事件
直接赋值给节点的事件
var dom = document.getElementId('xx')
dom.onclick = function(e){
// todo
}
DOM2级事件
它会经历3个阶段:
假设所有元素都绑定事件情况, 执行的顺序是 捕获 - 目标 - 冒泡;
- 捕获: 从上往下,从 window 向下捕获: event.target,到达目标元素;
- 到达目标元素: 事件已达到目标元素; (在目标上同时存在捕获和冒泡事件时, 先定义什么,就执行什么. 其非目标节点不会这样)
- 冒泡: 从下往上,从当前元素向父节点不断传递;
var dom = document.getElementId('xx')
dom.addEventListern('click', function(e) {
// todo
}, useCapture=true)
dom0 和 dom2 区别
事件的绑定js实现【捕获/冒泡】
-
onclick (dom0): 所有浏览器保持统一,只有冒泡,旧事件会被替代;
-
addEventListener (dom2): 可以自由设置 捕获 或 冒泡;缺点是早期 IE 只有冒泡;
DOM2 事件 addEventLitern 详解
addEventListener方法具有第三个可选参数 useCapture
其默认值为false,事件将在 冒泡阶段中发生;
如果为true,则事件将在 捕获阶段 中发生。
根据 addEventListener 的第三个参数只能是二选一;
委托事件执行过程中, e.target 和 e.currentTarget 区别?
e.target : 目标元素;
e.currentTarget: 冒泡/捕获 阶段的执行元素;
委托事件是根据什么事件流实现的?
- 在最上层的元素上绑定事件的处理函数;
- 自顶层节点向目标元素执行
- 委托事件内写判断 e.target === e.currentTarget 处理目标元素;
- 委托事件结束;
优点: 解决性能问题,减少绑定多个事件的大小占用的优点;
目标元素执行顺序是不是按照 事件定义 顺序?????
不会严格按照 捕获 - 到达目标 - 冒泡 的顺序来处理;
真实情况:目标元素的执行顺序,是按照绑定的顺序处理的;【参考文章里有案例,先绑定在什么阶段就会先执行】
真实业务里,如果一个元素绑定了两次事件,执行的顺序至关重要,需要知道这个知识点;
如何阻止冒泡?
- addEventListener: 使用 e.stopPropagation 都能阻止 捕获/冒泡;
特点: stopPropagation 在同一个元素绑定多个事件时,stopPropagation 执行后会阻止掉该元素其他绑定事件;【具体阻止哪些,和事件阶段绑定顺序有关系 】
如何阻止默认行为?
- return e.preventDefault 标准技术
- return e.returnValue 早期IE的
- return false 阻止对象属性的事件【onclick 绑定事件】
function cancelHandler(event){
var event=event||window.event;//兼容IE
//取消事件相关的默认行为
if(event.preventDefault) //标准技术
event.preventDefault();
if(event.returnValue) //兼容IE9之前的IE
event.returnValue=false;
return false; //用于处理使用对象属性注册的处理程序
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡</title>
</head>
<body>
<div>
<p id="parEle">我是父元素 <span id="sonEle">我是子元素</span></p>
</div>
</body>
</html>
<script type="text/javascript">
var sonEle = document.getElementById('sonEle');
var parEle = document.getElementById('parEle');
parEle.addEventListener('click', function () {
alert('父级 冒泡');
}, false);
parEle.addEventListener('click', function () {
alert('父级 捕获');
}, true);
sonEle.addEventListener('click', function () {
alert('子级冒泡');
}, false);
sonEle.addEventListener('click', function () {
alert('子级捕获');
}, true);
</script>
DOM3 事件
一些特殊事件: focus、blur、scroll 等等(待后续更新)