请说说focus、blur与focusin、focusout的区别是什么?
在前端开发中,focus、blur、focusin 和 focusout 都是与元素焦点相关的事件,但它们之间存在一些关键区别:
1. 事件冒泡:
focus和blur事件不冒泡。这意味着当一个元素获得或失去焦点时,只有该元素本身会触发这些事件,其父元素不会收到通知。focusin和focusout事件会冒泡。这意味着当一个元素获得或失去焦点时,该元素本身会触发事件,并且事件会沿着 DOM 树向上传播,触发其祖先元素上的相应事件。
2. 事件触发顺序:
当一个元素获得焦点时,事件触发的顺序是:focusin -> focus。
当一个元素失去焦点时,事件触发的顺序是:blur -> focusout。
3. 使用场景:
-
由于
focus和blur不冒泡,它们更适用于处理特定元素的焦点变化,例如:- 表单验证:在
blur事件中检查输入字段的值是否有效。 - UI 更新:在
focus事件中高亮输入框,在blur事件中移除高亮。
- 表单验证:在
-
由于
focusin和focusout会冒泡,它们更适用于处理包含多个可聚焦元素的容器的焦点变化,例如:- 跟踪焦点:监听容器的
focusin和focusout事件,可以知道焦点是否在容器内,而无需监听每个子元素。 - 动态添加/移除事件监听器:在容器的
focusin事件中为获得焦点的元素添加事件监听器,在focusout事件中移除监听器。
- 跟踪焦点:监听容器的
总结:
| 特性 | focus | blur | focusin | focusout |
|---|---|---|---|---|
| 冒泡 | 否 | 否 | 是 | 是 |
| 触发时机 | 元素获得焦点 | 元素失去焦点 | 元素获得焦点(冒泡阶段) | 元素失去焦点(冒泡阶段) |
| 常用场景 | 处理特定元素的焦点变化 | 处理特定元素的焦点变化 | 处理容器的焦点变化 | 处理容器的焦点变化 |
示例:
<div id="container">
<input type="text" id="input1">
<input type="text" id="input2">
</div>
<script>
const container = document.getElementById('container');
const input1 = document.getElementById('input1');
const input2 = document.getElementById('input2');
container.addEventListener('focusin', (event) => {
console.log('Container focusin:', event.target.id);
});
container.addEventListener('focusout', (event) => {
console.log('Container focusout:', event.target.id);
});
input1.addEventListener('focus', () => {
console.log('Input 1 focus');
});
input1.addEventListener('blur', () => {
console.log('Input 1 blur');
});
input2.addEventListener('focus', () => {
console.log('Input 2 focus');
});
input2.addEventListener('blur', () => {
console.log('Input 2 blur');
});
</script>
在这个例子中,当你点击 input1 时,控制台会输出: Container focusin: input1 -> Input 1 focus。 当你再点击 input2 时,控制台会输出:Input 1 blur -> Container focusout: input1 -> Container focusin: input2 -> Input 2 focus. 这清晰地展示了事件的冒泡行为和触发顺序。
浙公网安备 33010602011771号