DOM事件模型

124 阅读2分钟

一 什么是DOM事件模型

  1. 请看如下代码,当点击son时,算不算点击了parent?答案是算
  2. 那么如果此时parent和son分别绑定点击事件fn1和fn2,那么先执行fn1还是fn2呢?答案是不一定。因为浏览器同时支持两种顺序,先执行fn1再执行fn2的顺序,和先执行fn2再执行fn1的顺序。具体哪种执行方式在绑定监听事件的时候指定。
  <div class="parent">
     <div class="son">
     </div>
  </div>

二 DOM2级事件模型

  1. 事件捕获和事件冒泡的机制如下图
  2. 首先事件捕获阶段,按"window->document->html->body->......->目标元素"的顺序有没有函数监听,接着事件冒泡阶段,反向传递。整个过程中,有监听函数就调用,并提供事件信息,没有就跳过
  3. 无论绑定事件时,选择捕获阶段执行还是冒泡阶段执行,仅仅只是选择绑定事件函数在那个阶段执行,这两个阶段最终都会经历,而且是捕获阶段,冒泡阶段。

三 事件绑定API

  1. 在DOM2级事件模型中使用addEventListener和removeEventListener来注册和解除事件(IE8及之前版本不支持)。这种函数较之之前的方法好处是一个dom对象可以注册多个相同类型的事件,不会发生事件的覆盖,会依次的执行各个事件函数。
  2. 由于事件捕获阶段没有可以阻止事件的函数,所以一般都是设置为事件冒泡。
  addEventListener('事件名称','事件回调',bool('捕获/冒泡'))
  //bool为true代表捕获事件,bool不传或falsy代表冒泡事件,也就是选择将函数放在捕获阶段还是冒泡阶段

四 Event 对象有哪些常用应用?

  1. 阻止默认事件:event.preventDefault(),有些事件不能阻止默认动作,(scroll事件)
  2. 阻止冒泡:event.stopPropagation(),所有冒泡都可取消
  3. 阻止调用相同事件的其他侦听器(事件响应优先级):event.stopImmediatePropagation()
  4. 当前绑定事件的元素:event.currentTarget
  5. 当前被点击的元素:event.target

五 举例

  1. 输出2,1
  <div class="test1">
      <div class="test2"></div>
  </div>
  <script>
      document.querySelector('.test1').addEventListener('click',function () {
          console.log(1)
      })
      document.querySelector('.test2').addEventListener('click',function () {
          console.log(2)
      })
  </script>
  1. 输出1,2
  <div class="test1">
      <div class="test2"></div>
  </div>
  <script>
      document.querySelector('.test1').addEventListener('click', function () {
          console.log(1)
      }, true)
      document.querySelector('.test2').addEventListener('click', function () {
          console.log(2)
      }, true)
  </script>
  1. 输出2,1
  <div class="test1">
      <div class="test2"></div>
  </div>
  <script>
      document.querySelector('.test1').addEventListener('click', function () {
          console.log(1)
      })
      document.querySelector('.test2').addEventListener('click', function () {
          console.log(2)
      }, true)
  </script>
  1. 输出1,2
  <div class="test1"></div>
  <script>
      document.querySelector('.test1').addEventListener('click', function () {
          console.log(1)
      })
      document.querySelector('.test1').addEventListener('click', function () {
          console.log(2)
      }, true)
  </script>

六 如何阻止滚动

  1. 要阻止scroll,可阻止wheel和touchstart的默认动作,再让CSS让滚动条的width:0;
  2. CSS也行,使用overflow:hidden可以直接取消滚动条,但此时JS仍然可以修改scrollTop