请说说focus、blur与focusin、focusout的区别是什么?

在前端开发中,focusblurfocusinfocusout 都是与元素焦点相关的事件,但它们之间存在一些关键区别:

1. 事件冒泡:

  • focusblur 事件不冒泡。这意味着当一个元素获得或失去焦点时,只有该元素本身会触发这些事件,其父元素不会收到通知。
  • focusinfocusout 事件会冒泡。这意味着当一个元素获得或失去焦点时,该元素本身会触发事件,并且事件会沿着 DOM 树向上传播,触发其祖先元素上的相应事件。

2. 事件触发顺序:

当一个元素获得焦点时,事件触发的顺序是:focusin -> focus

当一个元素失去焦点时,事件触发的顺序是:blur -> focusout

3. 使用场景:

  • 由于 focusblur 不冒泡,它们更适用于处理特定元素的焦点变化,例如:

    • 表单验证:在 blur 事件中检查输入字段的值是否有效。
    • UI 更新:在 focus 事件中高亮输入框,在 blur 事件中移除高亮。
  • 由于 focusinfocusout 会冒泡,它们更适用于处理包含多个可聚焦元素的容器的焦点变化,例如:

    • 跟踪焦点:监听容器的 focusinfocusout 事件,可以知道焦点是否在容器内,而无需监听每个子元素。
    • 动态添加/移除事件监听器:在容器的 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. 这清晰地展示了事件的冒泡行为和触发顺序。

posted @ 2024-12-11 09:33  王铁柱6  阅读(626)  评论(0)    收藏  举报