DOM事件流

DOM

DOM(Document Object Model) 全称文档对象模型. 文档可以是HTML, XML, 或者XHTML文档.DOM定义 的是一组与平台和语言的接口. 目前形成了三个演进的标准, DOM Level 1, DOM Level 2, DOM Level 3. 每个新的Level都是在原有的基础之上增加了新的接口.

DOM事件流

可以看到, 在DOM Level 2里引入了事件, 主要有EventTarget, Mouse等接口. DOM Level 2里主要引入了键盘事件.

Event事件流

监听器 target.addEventListener(type, listener[, useCapture])的第三个参数useCapture, 类型为布尔, 默认为false,表示事件触发使用冒泡流. 先触发内层元素的监听器, 再触发外层元素的监听器. useCapture取值为true时, 将先触发外层元素的监听器, 再触发内层元素的监听器.

根据DOM2级事件规定
共有三个事件阶段:捕获阶段、目标阶段和气泡阶段。如在 dispatch之前调用stopPropagation() , 则将跳过所有阶段
捕获阶段:事件对象通过目标的祖先从窗口传播到目标的父对象。这个阶段也被称为捕获阶段。

目标阶段:事件对象(event object)到达事件对象的事件目标(event target)。这个阶段也被称为at-target阶段。如果事件类型指示事件不冒泡,则事件对象将在完成此阶段之后停止。

气泡阶段:事件对象以相反顺序传播目标的祖先,从event target的父对象开始,并以窗口结束。这个阶段也称为冒泡阶段。

DOM事件流

配合代码理解. 此处我们点击的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div class="main">
        <div class="btn-wrap">
            <button id="btn">点击</button>
        </div>
    <div>
    <script type="text/javascript">
        var btn=document.querySelector("#btn"),
            btnWrap=document.querySelector(".btn-wrap"),
            main=document.querySelector(".main"),
            body=document.querySelector("body"),
            html=document.querySelector("html");
            //冒泡
            btn.addEventListener("click",function(){
                console.log("你点击了ID为btn的button元素!");
            },false);
            btnWrap.addEventListener("click",function(){
                console.log("你点击了class为btn-wrap的DIV元素!");
            },false);
            main.addEventListener("click",function(){
                console.log("你点击了class为main的DIV元素!");
            },false);
            body.addEventListener("click",function(){
                console.log("你点击了body元素!");
            },false);
            html.addEventListener("click",function(){
                console.log("你点击了html元素!");
            },false);
            document.addEventListener("click",function(){
                console.log("你点击了document对象!");
            },false);

            //捕获
            btn.addEventListener("click",function(){
                console.log("你点击了ID为btn的button元素!");
            },true);
            btnWrap.addEventListener("click",function(){
                console.log("你点击了class为btn-wrap的DIV元素!");
            },true);
            main.addEventListener("click",function(){
                console.log("你点击了class为main的DIV元素!");
            },true);
            body.addEventListener("click",function(){
                console.log("你点击了body元素!");
            },true);
            html.addEventListener("click",function(){
                console.log("你点击了html元素!");
            },true);
            document.addEventListener("click",function(){
                console.log("你点击了document对象!");
            },true);
    </script>
</body>
</html>

如果我们点击btn,也可以视为同时点击了btn的容器元素, 甚至单击了整个页面. 因为我们于每一级元素都添加了监听器, 控制台打印结果如下.

DOM事件流

Event相关易混淆关键词

  • EventTarget / event.Target

    能用addEventListener方法添加事件监听器的对象都是EventTarget.
    Element,document 和 window 是最常见的EventTarget.

    event.Target, 是触发当前事件的最小单位元素.

  • event.currentTarget / event.Target

    event.Target返回触发事件的元素;event.currentTarget返回绑定事件的元素

    具体的说就是event.currentTarget是注册事件时所指向的元素,而event.Target是响应事件的最小子元素,也就是最深层级的触发事件的元素。

    涉及到事件委托时, 这两个所指的元素才会不一样.

参考:
https://www.cnblogs.com/johnn... DOM等级概述
https://www.w3.org/TR/DOM-Lev... W3C事件流

相关推荐