JavaScript(八股试题001):不会冒泡的事件有哪些
·
题目:不会冒泡的事件有哪些?
1. 背景知识
在 JavaScript 的 DOM 事件模型中,大部分事件都会按“冒泡阶段”从目标元素向上传递到 document。
事件流程
- 捕获阶段:从
document一层层向下到目标元素 - 目标阶段:在目标元素上触发
- 冒泡阶段:从目标元素向上传递到
document
但有些事件触发后不会进入冒泡阶段,这意味着它们只会在目标元素上触发一次,不会传递给父元素。
2. 常见不会冒泡的事件列表
| 事件名 | 说明 | 备注 |
|---|---|---|
focus |
元素获取焦点 | 直接触发在目标元素 |
blur |
元素失去焦点 | 直接触发在目标元素 |
focusin |
类似 focus,但会冒泡,所以是例外形式 |
|
focusout |
类似 blur,但会冒泡 |
|
load |
资源加载完成时触发(img 等) | 不冒泡 |
unload |
页面即将被关闭/离开时触发 | 不冒泡 |
stop |
多媒体播放停止 | audio/video 相关 |
readystatechange |
document.readyState 改变时触发 |
主要用于 readystatechange 回调 |
scroll |
元素或窗口滚动 | 在元素上触发,不冒泡 |
3. 关键点注意
focus/blur不会冒泡focusin/focusout(对应的事件)是特殊的,它们会冒泡scroll事件经常被误认为会冒泡,其实不会- 这些事件一般用在目标元素上监听,而不是绑定在父元素去代理
4. 代码实验对比
<!DOCTYPE html>
<html>
<head>
<style>
.parent {
width: 300px;
height: 200px;
background-color: lightblue;
padding: 20px;
}
.child {
width: 150px;
height: 100px;
background-color: lightcoral;
}
.log {
margin-top: 20px;
height: 200px;
overflow-y: auto;
border: 1px solid #ccc;
padding: 10px;
}
</style>
</head>
<body>
<div id="parent" class ="parent">
Parent
<input type="text" id="child" placeholder="Click me" class="child">
</div>
<div id="log" class ="log"></div>
<script>
const parent = document.getElementById('parent');
const child = document.getElementById('child');
const log = document.getElementById('log')
// 父元素监听 focus
parent.addEventListener('focus', () => {
log.innerHTML += `Parent focus<br>`;
});
// 父元素监听 focusin(冒泡的版本)
parent.addEventListener('focusin', () => {
log.innerHTML += `Parent focusin<br>`;
});
// 子元素监听 focus
child.addEventListener('focus', () => {
log.innerHTML += `Child focus<br>`;
});
</script>
</body>
</html>

预期结果:
- 点击输入框 → 输出:
Child focus Parent focusinParent focus没触发,因为focus不冒泡;
但focusin会冒泡到 parent。
5. Mermaid 事件传递对比
focus(不会冒泡)
focusin(会冒泡)
6. 使用场景建议
- 不会冒泡的事件
- 必须绑定在目标元素本身
例如:input.addEventListener('focus', handler);
- 必须绑定在目标元素本身
- 会冒泡的同类事件
- 可以利用事件代理,提高代码效率
例如:parent.addEventListener('focusin', handler);
- 可以利用事件代理,提高代码效率
7. 刷题总结(答题模板)
在 JS 中,大多数事件会冒泡,但以下常见事件不会冒泡:
focus、blur、load、unload、stop、readystatechange、scroll。
特别地,focus/blur不会冒泡,但它们的对应版本focusin/focusout会冒泡。
实际开发中,如果希望用代理监听焦点变化,可以用focusin和focusout代替。
个人理解:不会冒泡的你要监听触发的子元素本身,会冒泡的你只需要监听父元素就可以得到子元素是否触发的消息。
更多推荐


所有评论(0)