文章目录
1. 事件冒泡
-
定义:
结构上 ( 而非视觉上 ) 嵌套关系的元素, 会存在事件冒泡的功能
即同一事件, 自子元素冒泡向父元素 ( 自底向上 ) -
代码示例
建立一个 3 层嵌套结构, 最外层到最内层的 div 的 id 分别为 theOUTER, theMIDDLE 和 theINNER
同时, 全部容器都分别绑定点击事件, 点击后在后台输出其 id
<div id="theOUTER" style="background-color: red; width: 300px; height: 300px;" οnclick="console.log('theOUTER')">
<div id="theMIDDLE" style="background-color: green; width: 200px; height: 200px;" οnclick="console.log('theMIDDLE')">
<div id="theINNER" style="background-color: blue; width: 100px; height: 100px;" οnclick="console.log('theINNER')">
</div>
</div>
</div>
- 效果图示
- 点击事件效果
点击最内层的容器 theINNER 后, 会触发事件的冒泡, 从内到外分别触发每个容器的事件
最后可见, 从输出结果可知, 冒泡是从嵌套关系的最内层到最外层进而触发的
2. 事件捕获
- 定义:
结构上 ( 而非视觉上 ) 嵌套关系的元素, 会存在事件捕获的功能
即同一事件, 自父元素捕获至子元素 ( 事件源元素 ) ( 自顶向下 )
- 代码示例
事件监听器的第三个参数改为 true, 就会启用事件捕获模型, 关闭事件冒泡模型
依旧是那三个容器, 现在分别给他们用事件监听器绑定事件, 并启用事件捕获模型
<div id="theOUTER" style="background-color: red; width: 300px; height: 300px; font-weight: bold; color: white; text-align:end">
theOUTER
<div id="theMIDDLE" style="background-color: green; width: 200px; height: 200px;">
theMIDDLE
<div id="theINNER" style="background-color: blue; width: 100px; height: 100px;">
theINNER
</div>
</div>
</div>
<script>
function sayid() {
console.log(this.id);
};
var theOUTER = document.getElementById('theOUTER');
theOUTER.addEventListener('click', sayid, true);
var theMIDDLE = document.getElementById('theMIDDLE');
theMIDDLE.addEventListener('click', sayid, true);
var theINNER = document.getElementById('theINNER');
theINNER.addEventListener('click', sayid, true);
</script>
- 效果图示
- 触发点击效果
从输出结果可见, 事件捕获模型是从最外层的父元素到最内层的子元素依次对事件进行捕获且触发的
3. 事件模型的一些注意点
(1) 两种模型共同存在时触发的顺序
- 有时候会有两种模型共存, 这个时候触发顺序是, 先捕获, 后冒泡
- 代码示例
上半部分的事件绑定才用捕获模型, 下半部分的则才用冒泡模型
function sayid() {
console.log(this.id);
};
var theOUTER = document.getElementById('theOUTER');
theOUTER.addEventListener('click', sayid, true);
var theMIDDLE = document.getElementById('theMIDDLE');
theMIDDLE.addEventListener('click', sayid, true);
var theINNER = document.getElementById('theINNER');
theINNER.addEventListener('click', sayid, true);
function sayidpop() {
console.log(this.id + 'pop');
};
theOUTER.addEventListener('click', sayidpop, false);
theMIDDLE.addEventListener('click', sayidpop, false);
theINNER.addEventListener('click', sayidpop, false);
- 触发点击事件
显然, 先触发的是捕获模型, 然后再触发的是冒泡模型
(2) 不触发冒泡的事件
- focus, blur, change, submit, reset, select etc…
4. 取消冒泡
- 大多时候都不希望点击一个容器其它容器功能都会被触发, 因此需要取消冒泡模型
(1) 语法
- 在不想发生冒泡的函数体内部加上
event.stopPropagation()
或event.cancelBubble = true
即可取消冒泡
(2) 示例
function sayidpop() {
event.cancelBubble = true;
console.log(this.id + 'pop');
};
- 效果
显而易见, 现在点击事件并不会触发父容器的冒泡
5. 阻止默认事件
(1) 默认事件
表单提交, a 标签跳转, 右键出现菜单等事件都是默认事件
(2) 语法
- 1).
return false;
以对象属性的方式注册的事件才生效; - 2).
event.preventDefault();
函数体内部加入即可 - 3).
event.returnValue = false;
函数体内加入
(3) 示例
取消 a 标签的跳转事件
<a id="theLINK" href="https://www.baidu.com/" target="_blank">XXXXXXXXXXXXXXXXX</a>
<script>
var theLINK = document.getElementById('theLINK');
theLINK.addEventListener('click',
function () {
event.preventDefault();
},
false);
</script>
也可以通过这种方式取消
<a id="theLINK" href="https://www.baidu.com/" target="_blank"
onclick="return false;">XXXXXXXXXXXXXXXXX</a>