w3c事件模型中的事件:首先是捕获阶段,达到目标阶段,再进入冒泡阶段。
attachEvent()采用冒泡方式,而addEventListener()可以采用冒泡或事件捕获方式
document.body.addEventListener('click', ()=>{}, true)
事件冒泡
事件开始的节点元素接收,然后传播至上级
举个栗子:
层级关系: document > html > body > div > span > button
<!DOCTYPE html><html><body><div onclick="divClick()"><span onclick="spanClick()"><button onclick="butClick()">点击</button></span></div></body><script>function butClick() {console.log('button');}function spanClick() {console.log('span');}function divClick() {console.log('div');}document.body.onclick = () => {console.log('body');}</script></html>
输出结果:
输出顺序: button > span > div > body > html > document
图片示例:
事件捕获
上一节点接收事件,然后向下传播到具体节点元素
举个栗子:
层级关系: document > html > body > div > span > button
<!DOCTYPE html><html><body><div id="div"><span id="span"><button id="button">点击</button></span></div></body><script>const body = document.body;const div = document.querySelector('div');const span = document.querySelector('span');const button = document.querySelector('button');div.addEventListener('click', (event) => {console.log('div');}, true); // false 为冒泡事件、true为捕获事件span.addEventListener('click', (event) => {console.log('span');}, true);button.addEventListener('click', (event) => {console.log('button');}, true);body.addEventListener('click', (event) => {console.log('body');}, true);</script></html>
输出结果:
输出顺序: body > div > span > button
图片示例:
DOM事件流
事件先是从 捕获事件开始,再到目标事件,最后冒泡事件。
举个栗子:
<!DOCTYPE html><html><body><div id="div"><button onclick="buttonClick()">点击</button></div></body><script>const body = document.body;const div = document.querySelector('div');const button = document.querySelector('button');const buttonClick = (event) => {console.log('button');}; // 目标事件div.addEventListener('click', (event) => {console.log('div');}, false); // 冒泡事件body.addEventListener('click', (event) => {console.log('body');}, true); // 捕获事件</script></html>
输出结果:
输出顺序:捕获事件 > 目标事件 > 冒泡事件
图片示例:
阻止事件冒泡
w3c模型:调用事件的event.stopPropagation()方法
微软的模型: 设置事件的cancelBubble的属性为true
document.body.addEventListener('click', (event) => {if(event){event.stopPropagation();}else{window.event.cancelBubble = true;}}, false);// React框架阻止冒泡的方法const click = (event)=>{event.nativeEvent.stopImmediatePropagation();}
举个栗子:
<!DOCTYPE html><html><body><div id="div"><button id="button">点击</button></div></body><script>const body = document.body;const div = document.querySelector('div');const button = document.querySelector('button');button.addEventListener('click', (event) => {console.log('button');if(event){event.stopPropagation();}else{window.event.cancelBubble = true;}}, false);div.addEventListener('click', (event) => {console.log('div');}, false);body.addEventListener('click', (event) => {console.log('body');}, false);</script></html>
输出结果:
