JS 的事件

102 阅读3分钟

一、事件传播

假设我们在浏览器内用一个宽高500px的盒子,内部有一个水平垂直都居中的子级盒子,宽高为100px

当我点击在子级盒子上的时候,其实也是点击在了这个父级盒子的身上

这种情况就叫做事件传播

  • 当元素触发一个事件的时候,这个元素的父级节点也会触发相同的事件,父元素的父元素也会触发相同的事件
  • 点击了子级盒子,会触发子级盒子的点击事件
  • 也是点在了父级盒子上,也会触发父级盒子的点击事件
  • 也是点在了 body 上,也会触发 body 的点击事件
  • 也是点在了 html 上,也会触发 html 的点击事件
  • 也是点在了 document 上,也会触发 document 的点击事件
  • 也是点在了 window 上,也会触发 window 的点击事件
  • 页面上任何一个元素触发事件,都会一层一层的最终导致window的相同事件触发
  • 前提是一定得有事件

注意点

  • 1.只会传播同类事件,如果是点击事件,那么只会触发父级或者父级的父级注册的点击事件,其他类型的事件不会触发
  • 2.只会从点击的元素开始,按照html的结果,逐层向上触发同类型的事件
  • 3.内部元素不管有没有该事件,只要上层元素有该事件,那么上层元素的事件就会触发
<html>
    <style>
        *{
          margin: 0;
          padding: 0;
        }

        .box {
          width: 300px;
          height: 300px;
          background-color: pink;
        }

        .sBox {
          width: 100px;
          height: 100px;
          background-color: green;
        }
    </style>
<body>
    <div class="box">
        <div class="sBox"></div>
    </div>
  <script>
    // 0. 获取元素
    var sBox = document.querySelector('.sBox')
    var box = document.querySelector('.box')
    var oBody = document.body

    sBox.onclick = function () {
      console.log('我是内层div,我的点击事件被触发了')
    }
    box.onclick = function () {
      console.log('我是外层div,我的点击事件被触发了')
    }
    oBody.onclick = function () {
      console.log('我是body,我的点击事件被触发了')
    }
  </script>
</body>
</html>

二、事件的冒泡与捕获 目标

目标:你点击在哪个元素上,那么这个事件的目标就是这个元素

事件的冒泡与捕获(面试题)

冒泡:就是从目标的事件处理函数开始,依次向上,一直到window的事件处理函数触发

也就是说从下向上的执行事件处理函数

捕获:就是从window的事件处理函数开始,依次向下,一直到目标的事件处理函数触发

也就是说从上向下的执行事件处理函数

区别:就是在事件的传播中,多个同类型的事件处理函数的执行顺序不同,仅此而已

三、事件委托

就是要把我自己做的事,委托给别人帮我完成

因为我们的冒泡机制,点击子元素的时候,也会同步触发父元素的相同事件

所以我们可以把子元素的事件委托给父元素来做

点击子元素的时候,不管子元素有没有点击事件,只要父元素有点击事件,那么就可以触发父元素的点击事件

target

这个属性是事件对象里的属性,表示你点击的目标

target兼容性有问题,在IE浏览器内需要使用srcElement 语法:e.srcElement (了解即可)

事件委托的优点

  • 页面上本身没有li,通过代码添加了一些li

  • 这些li是没有点击事件的,每次动态的添加li,还需要重新给li绑定一次点击事件

  • 这时候使用事件委托就比较合适

  • 因为:新加进来的li也是ul的子元素,点击的时候也可以触发 ul的点击事件

var oUl = document.querySelector('ul')
    oUl.onclick = function (e) {
      if(e.target.nodeName === 'LI'){
        console.log('我是li标签,我被点击了~~~')
      }
    }

四、默认行为

默认行为:不用我们注册,但是自己存在的事情

比如:鼠标右键单击,会弹出一个菜单

点击a标签后,自己会跳转到页面

这些不需要我们注册就能实现的事情,我们叫做默认事件

阻止默认事件

不希望浏览器执行默认事件时,比如点击a标签,不跳转页面,那么就需要阻止默认事件

两种方式

1.e.preventDefault() --- 非IE浏览器

2.e.returnValue = false --- IE浏览器(了解即可)

var oA = document.querySelector('a')
    oA.onclick = function (e) {
      console.log('该函数执行,拦截掉了 a 标签的默认行为')
      e.preventDefault()
    }