JavaScript-浅谈DOM事宜流

什么是事宜?(敲黑板)

事宜,就是文档或浏览器窗口发作的一些特定的交互霎时。(by 《JavaScript高等程序设计》)
比方鼠标点击,双击,滚动条滑动…

什么是事宜流?

先来看一个简朴的例子:

<!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>
</body>
</html>

这时候我们点击btn的同时,也能够视为同时点击了btn的容器元素,以至单击了全部页面。
事宜流指的是从页面吸收事宜的递次。
关于事宜流,IE和Netscape提出了差不多相反的观点,IE提出的就是广为人知的事宜冒泡流,而Netscape提出的则是事宜捕捉流

1. 事宜冒泡

事宜冒泡,即事宜开始时由最详细的元素吸收,如上面例子中的btn,然后逐步向上级流传到较为不详细的节点。DOM2级事宜划定addEventListener要领的第三个参数设为false,示意事宜在冒泡阶段触发。

注:运用频仍的事宜托付现实上也是应用了事宜冒泡。

照样雷同的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);
    </script>
</body>
</html>

假如我们点击btn,那末这个click事宜的流传递次以下:
《JavaScript-浅谈DOM事宜流》

也就是,click事宜起首在btn元素上触发,而这个元素就是我们单击的元素,然后click事宜沿DOM树向上流传,在每一级的节点都邑发作,直至流传到document对象。
一切当代浏览器都支撑事宜冒泡。

2. 事宜捕捉

事宜捕捉,即事宜从不太肯定的节点吸收,然后向下流传到最详细的节点,事宜捕捉的意图在于在事宜抵达预期目的之前捕捉它。DOM2级事宜划定addEventListener要领的第三个参数设为true,示意事宜在捕捉阶段触发。
照样雷同的DOM构造为例:
将参数改成true

<!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元素!");
            },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,那末这个click事宜的流传递次以下:
《JavaScript-浅谈DOM事宜流》

在事宜捕捉过程当中,document对象起首吸收到click事宜,然后事宜沿着DOM树顺次向下流传。
现在支撑事宜捕捉流的浏览器有:IE9,Safari,Chrome,Opera,Firefox。
因为老版本浏览器不支撑事宜捕捉,发起人人更多的是用事宜冒泡,在有特殊需要时再运用事宜捕捉。

3. DOM事宜流

依据DOM2级事宜划定,事宜流应当包含三个阶段,事宜捕捉阶段,处于目的阶段和事宜冒泡阶段。
照样雷同的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,那末这个click事宜的流传递次以下:
《JavaScript-浅谈DOM事宜流》

在DOM事宜流中,现实的目的btn不会吸收到事宜。这意味着在捕捉阶段,事宜从document到btn-wrap就住手了,下一阶段是“处于目的”阶段,因而事宜在btn上发作,然后冒泡阶段发作,事宜又流传回文档。

注:多半支撑DOM事宜流的浏览器都完成了一种特定行动,纵然DOM2级事宜范例明确要求捕捉阶段不会触及目的阶段,IE9,Safari,Chrome,Firefox,Opera9.5及更高版本都邑在事宜捕捉阶段触发事宜对象上的事宜,这也是上图btn被触发两次的缘由。
IE9,Safari,Chrome,Firefox,Opera都支撑DOM事宜流,IE8及更早版本不支撑DOM事宜流。

本文学问点大多来自《JavaScript高等程序设计》一书,博主在这里也是做一次总结,稳固一下相干学问,同时也愿望没打仗过事宜流的童鞋们,有一个也许的观点。

    原文作者:sivan_
    原文地址: https://segmentfault.com/a/1190000006829483
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞