js事件
概念:HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件、页面的滚动事件onscroll等等,当页面产生一个事件时,该事件会在元素节点与根节点之间的路径传播,路径所经过的节点都会收到该事件,这个传播的过程叫做DOM事件流
一. 当页面产生一个事件时经过的三个阶段:
- 事件捕获阶段
document顶部先接收到事件,依次往下传播到事件节点(可以借用addEventListener来模拟事件捕获流) - 处于目标阶段
- 事件冒泡阶段
事件开始时由最具体的元素接收,然后逐级向上传播
执行流程:
示例代码:
说明: addEventListener 第一个参数: 事件名称, 第二个参数: 触发函数, 第三个参数: 布尔 默认false, true表示捕获阶段触发, fals事件冒泡阶段
三:js阻止事件冒泡和默认事件
阻止事件冒泡:
w3c:e.stopPropagation
ie:window.event.cancelBubble = true
默认事件:是指目标元素的默认行为比如a标签会跳转链接 form会提交表单
w3c:e.preventDefault()
ie:window.event.returnValue = false
另外js中的return false也可以阻止默认行为,jq中的return false既可以阻止默认行为也可以阻止冒泡
// 事件绑定的方式, 用return false; 不会阻止默认事件
oBtn.addEventListener('click', function (e) {
console.log('btn处于事件冒泡阶段 - 5');
return false;
}, false);
// 以下代码 return false;可以阻止
oBtn.onclick = function () {
return false;
};
return false ? 参考文章
四、target 和 currentTarget
event.target指向引起触发事件的元素,而event.currentTarget则是事件绑定监听的元素。
五、宏任务和微任务
macrotask(宏任务):主代码块,setTimeout,setInterval等(可以看到,事件队列中的每一个事件都是一个macrotask)
microtask(微任务):Promise,process.nextTick等
// 代码1
async function async1() {
console.log(1);
await async2();
console.log(3);
}
// 代码2
async function async2() {
console.log(2);
}
// 代码3
Promise.resolve().then(() => {
console.log(4);
});
// 代码4
new Promise(function(resolve) {
console.log(7);
resolve()
}).then(function() {
console.log(8);
})
// 代码5
setTimeout(() => {
console.log(5);
});
async1();
console.log(6);
//输出 7 1 2 6 4 8 3 5
代码1、2定义异步函数。首先按主代码块顺序执行·代码3,由于异步函数返回,放入微任务[console.log(4)] 。主代码执行·代码4输出:7
,等待异步返回放到微任务[console.log(4),console.log(8)]。主代码执行·代码5放入宏任务[console.log(5)]。
然后执行async1(),输出:1
,async1()里面执行async2(),输出:2
。由于async2()返回结果是异步,加入微任务等待[console.log(4),console.log(8),console.log(3)]
最后主代码执行console.log(6)输出:6
。主代码执行完毕。
现在来看,微任务列表有 [console.log(4),console.log(8),console.log(3)]。宏任务有[console.log(5)]。
由于有微任务,先执行微任务,依次输出:4 8 3
,宏任务执行完成。
执行下一个宏任务[console.log(5)],输出:5