目录
1. 捕获阶段,document->html->body->father->son
2. 冒泡阶段 ,son->father->body->html->document
一、什么是DOM事件流
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程称为DOM事件流
二、事件捕获和冒泡
addEventListener(type,listener,useCapture) 第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false,表示在事件冒泡阶段调用事件处理程序
var father = document.querySelector('.father');
var son = document.querySelector('.son');
1. 捕获阶段,document->html->body->father->son
son.addEventListener('click', function() {
alert('son');
}, true)
father.addEventListener('click', function() {
alert('father');
}, true)
2. 冒泡阶段 ,son->father->body->html->document
son.addEventListener('click', function() {
alert('son');
}, false)
father.addEventListener('click', function() {
alert('father');
}, false)
document.addEventListener('click', function() {
alert('document');
}, false)
注意:有些事件是没有冒泡的,比如:onfoucs onblur onmouseenter onmouseleave
三、事件对象
1、 event就是一个事件对象, 写到函数的小括号里面, 当形参来看
2、 事件对象只有有了事件才会存在, 他是系统给我们自动创建的, 不需要传递参数
3、 事件对象, 是我们事件的一系列数据的集合, 跟事件相关的, 比如鼠标点击里面就包括了鼠标的相关信息, 鼠标坐标等;
4、 这个事件对象我们可以自己命名, 比如event、 e等
5、 事件对象也有兼容性问题, ie678可以通过window.event获取, 兼容性写法: e = e || window.event
var div = document.querySelector('div');
div.onclick = function(e) {
e = e || window.event;
console.log(e);
}
1. e.target 返回的是触发事件的对象
兼容性问题: ie678不支持,可以使用e.srcElement
div.onclick = function(e) {
e = e || window.event;
var target = e.target || e.srcElement;
console.log(target);
}
注意:this返回的是绑定事件的对象,区别:e.target 点击了哪个元素,就返回那个元素;this 指的是哪个元素绑定了点击事件,就返回哪个元素
2. e.type 返回事件类型
var div = document.querySelector('div');
div.addEventListener('click', fn);
div.addEventListener('mouseover', fn);
div.addEventListener('mouseout', fn);
function fn(e) {
console.log(e.type);
}
3. 阻止默认事件, 让链接不跳转或者让提交的按钮不提交
var a = document.querySelector('a');
a.addEventListener('click', function(e) {
e.preventDefault(); // dom 标准写法
})
4. 传统注册方式阻止默认事件
a.onclick = function(e) {
// 普通浏览器写法:e.preventDefault();
e.preventDefault(); // 方法
// 低版本浏览器 ie678 :e.returnValue
e.returnValue; // 属性
// return false; 这个也可以阻止默认行文,没有兼容性问题,但是写了之后,后面的代码就不执行了,而且只能在传统注册方式中使用
// return false;
}
5. 阻止冒泡
e.stopPropagation(); //dom推荐的标准, 阻止冒泡
e.cancelBubble = true; // 低版本浏览器阻止冒泡
if (e && e.stopPropagation) {
e.stopPropation();
} else {
window.event.cancelBubble = true;
}
四、事件委托
事件委托原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
<ul>
<li>知否知否,不知道啊</li>
<li>知否知否,不知道啊</li>
<li>知否知否,不知道啊</li>
<li>知否知否,不知道啊</li>
<li>知否知否,不知道啊</li>
</ul>
<script>
// 事件委托的核心原理:给父节点添加事件类型,利用事件冒泡影响每一个子节点
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e) {
for (var i = 0; i < ul.children.length; i++) {
ul.children[i].style.backgroundColor = '';
}
e.target.style.backgroundColor = 'skyblue';
});
</script>