DOM事件模型一(事件捕获、事件冒泡、事件流)

事件

事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。
事件通常与函数结合使用,函数不会在事件发生前被执行!

事件捕获

事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。
事件捕获的用意在于在事件到达预定目标之前就捕获它。
以下列HTML结构为例,说明事件冒泡、事件捕获及事件流。

// 示例一
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div>
    <button>点一下啦</button>
  </div>
</body>
</html>

如果单击了页面中的button元素,那么这个click事件首先由document捕获,然后沿DOM树向下传播,一直传播到事件的实际目标的上一个元素。

[注意]IE9、Firefox、Chrome、Safari等现代浏览器都支持事件捕获,但是从window对象开始捕获。

为各dom元素绑定click事件:

// Internet Explorer 8 及更早IE版本不支持 addEventListener() 方法
// addEventListener有第三个参数useCapture,其作用是指定事件是否在捕获或冒泡阶段执行。
// 可选值为:true(捕获),false(默认、冒泡)
// 示例二
<script>
document.querySelector('button').addEventListener('click', captureBtn, true)
document.querySelector('div').addEventListener('click', captureDiv, true)
document.body.addEventListener('click', captureBody, true)
document.documentElement.addEventListener('click', captureHtml, true)
document.addEventListener('click', captureDocument, true)
window.addEventListener('click', captureWindow, true)
function captureBtn(){console.log('capture button')}
function captureDiv(){console.log('capture button')}
function captureBody(){console.log('capture button')}
function captureHtml(){console.log('capture button')}
function captureDocument(){console.log('capture button')}
function captureWindow(){console.log('capture button')}
</script>

点击button,可见打印结果如下:
在这里插入图片描述

事件冒泡

IE的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。
同样以示例一的结构说明事件冒泡。
如果单击了页面中的button元素,那么这个click事件沿DOM树向上传播,在每一级节点上都会发生。

[注意]所有现代浏览器都支持事件冒泡,但在具体实现在还是有一些差别。IE9、Firefox、Chrome、Safari将事件一直冒泡到window对象,IE8以下事件冒泡到document。

为各dom元素绑定click事件:


// 示例三
<script>
document.querySelector('button').addEventListener('click', bubbleBtn)
document.querySelector('div').addEventListener('click', bubbleDiv)
document.body.addEventListener('click', bubbleBody)
document.documentElement.addEventListener('click', bubbleHtml)
document.addEventListener('click', bubbleDocument)
window.addEventListener('click', bubbleWindow)
function bubbleBtn(){console.log('bubble button')}
function bubbleDiv(){console.log('bubble button')}
function bubbleBody(){console.log('bubble button')}
function bubbleHtml(){console.log('bubble button')}
function bubbleDocument(){console.log('bubble button')}
function bubbleWindow(){console.log('bubble button')}
</script>

点击button,可见打印结果为:
在这里插入图片描述

事件流

DOM2级事件规定的事件流包括三个阶段:

  • 事件捕获阶段(capture phase):实际目标button在捕获阶段不会接收事件。也就是在捕获阶段,事件从window到div就停止了。
  • 处于目标阶段(target phase):事件在button上发生并处理。但是事件处理会被看成是冒泡阶段的一部分。
  • 事件冒泡阶段(bubbling phase):事件又传播回Document对象。

若将示例二、三中的事件监听全部加上,点击button,打印结果如下:
在这里插入图片描述

但实际上,由以上打印可看出:

  • 尽管“DOM2级事件”标准规范明确规定事件捕获阶段不会涉及事件目标,但是在IE9、Safari、Chrome、Firefox和Opera9.5及更高版本都会在捕获阶段触发事件对象上的事件。结果就是,我们有两次机会在目标对象上面操作事件。
  • 并非所有的事件都会经过冒泡阶段 。所有的事件都要经过捕获阶段和处于目标阶段,但是有些事件会跳过冒泡阶段。

梳理一下哪些事件不能冒泡

UI事件
  • load
  • unload
  • scroll
  • resize
焦点事件
  • blur
  • focus
鼠标事件
  • mouseleave
  • mouseenter
media相关事件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值