跳至主要內容

冒泡和捕获

Yang大约 1 分钟

事件处理阶段

event.eventPhase 可以获取事件的阶段数(capturing=1,target=2,bubbling=3)

  1. 捕获阶段:通过祖先链(从 Window 开始)向下到达元素
  2. 目标阶段:事件到达目标元素
  3. 冒泡阶段:事件从元素上开始冒泡,在途中调用处理程序

冒泡(bubbling)

当一个事件发生在一个元素上,会首先运行在该元素上的处理程序,然后运行其父元素上的处理程序,然后一直向上到其他祖先上的处理程序

  • 几乎所有的事件都会冒泡
    • focus 不会冒泡

event.target

引发事件的那个嵌套层级最深的元素(事件实际发生的位置)被称为目标元素,可以通过 event.target 访问

  • 是引发事件的目标元素,在冒泡过程中不会发生变化
  • this(同 event.currentTarget),表示当前元素

停止冒泡

冒泡事件从目标元素开始向上冒泡。通常,它会一直上升到 <html>,然后再到 document 对象,有些事件甚至会到达 window,它们会调用路径上所有的处理程序

event.stopPropagation()

用于停止冒泡,如果一个元素在一个事件上有多个处理程序,即使其中一个停止冒泡,其他处理程序仍会执行

event.stopImmediatePropagation()

用于停止冒泡,并阻止当前元素上的处理程序运行

捕获(capturing)

<!DOCTYPE HTML>
<html>

  <head>
    <meta charset="utf-8">
    <style>
      div,
      span,
      i {
        display: inline-block;
        padding: 24px;
        border: 1px solid #000;
      }
    </style>
  </head>

  <body>

    <div id="div">
      <span id="span">
        <i id="i">冒泡测试</i>
      </span>
    </div>

    <script>
      for (let elem of document.querySelectorAll('*')) {
        elem.addEventListener('click', () => {
          console.log(`Capture:${elem.tagName} - ${event.eventPhase}`)
        }, {
          capture: true
        })
        elem.addEventListener('click', () => {
          console.log(`Bubbling:${elem.tagName} - ${event.eventPhase}`)
        })
      }
    </script>

  </body>
</html>
上次编辑于:
贡献者: sunzhenyang