zoukankan      html  css  js  c++  java
  • 0169 DOM事件流/事件机制/事件模型/事件周期:捕获、触发,冒泡

    DOM事件流

    html中的标签都是相互嵌套的,我们可以将元素想象成一个盒子装一个盒子,document是最外面的大盒子。
    当你单击一个div时,同时你也单击了div的父元素,甚至整个页面。
    
    那么是先执行父元素的单击事件,还是先执行div的单击事件 ???
    

    事件流:描述的是从页面中接收事件的顺序。

    事件发生时会在元素节点之间按照特定顺序传播,这个传播过程DOM 事件流

    比如:我们给页面中的一个div注册了单击事件,当你单击了div时,也就单击了body,单击了html,单击了document。

    当时的2大浏览器霸主谁也不服谁!
    IE 提出从目标元素开始,然后一层一层向外接收事件并响应,也就是冒泡型事件流。
    Netscape(网景公司)提出从最外层开始,然后一层一层向内接收事件并响应,也就是捕获型事件流。
    
    江湖纷争,武林盟主也脑壳疼!!!
    最终,w3c 采用折中的方式,平息了战火,制定了统一的标准 —--— 先捕获再冒泡。
    现代浏览器都遵循了此标准,所以当事件发生时,会经历3个阶段。
    

    DOM 事件流会经历3个阶段:

    1. 捕获阶段

    2. 当前目标阶段

    3. 冒泡阶段

    我们向水里面扔一块石头,首先它会有一个下降的过程,这个过程就可以理解为从最顶层向事件发生的最具体元素(目标点)的捕获过程;之后会产生泡泡,会在最低点( 最具体元素)之后漂浮到水面上,这个过程相当于事件冒泡。

    注意

    1. JS 代码中只能执行捕获或者冒泡其中的一个阶段
    2. onclick 和 attachEvent 只能得到冒泡阶段。【因为attachEvent 是IE的。】
    3. addEventListener(type, listener[, useCapture])第三个参数如果是 true,表示在事件捕
      获阶段调用事件处理程序;如果是 false(不写默认就是false),表示在事件冒泡阶段调用事件处理
      程序。
    4. 实际开发中我们很少使用事件捕获,我们更关注事件冒泡。
    5. 有些事件是没有冒泡的,比如 onblur、onfocus、onmouseenter、onmouseleave 【 onblur、onfocus事件的目标元素的父元素没法获得、失去焦点。】
    6. 事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件,我们后面讲解。


    事件冒泡

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
            .father {
                 200px;
                height: 200px;
                background-color: pink;
            }
            
            .son {
                 100px;
                height: 100px;
                background-color: cyan;
            }
    </head>
    
    <body>
        <div class="father">
            <div class="son">son盒子</div>
        </div>
        <script>
            // 冒泡阶段:点击 son盒子,先后弹出 son、father、document
    
            // onclick 和 attachEvent(ie) 在冒泡阶段触发
            // 冒泡阶段 如果addEventListener 第三个参数是 false 或者 省略 
            // son -> father ->body -> html -> document
            var son = document.querySelector('.son');
            // 给son注册单击事件
            son.addEventListener('click', function() {
                alert('son');
            }, false);
    
            // 给father注册单击事件
            var father = document.querySelector('.father');
            father.addEventListener('click', function() {
                alert('father');
            }, false);
    
            // 给document注册单击事件,省略第3个参数
            document.addEventListener('click', function() {
                alert('document');
            })
        </script>
    </body>
    
    </html>
       
    

    事件捕获

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
            .father {
                 200px;
                height: 200px;
                background-color: pink;
            }
            
            .son {
                 100px;
                height: 100px;
                background-color: cyan;
            }
    </head>
    
    <body>
        <div class="father">
            <div class="son">son盒子</div>
        </div>
    
        <script>
            // 捕获阶段:点击 son盒子,先后弹出 document、father、son
    
            // 如果addEventListener() 第三个参数是 true 那么在捕获阶段触发
            // document -> html -> body -> father -> son
            var son = document.querySelector('.son');
            // 给son注册单击事件,第3个参数为true
            son.addEventListener('click', function() {
                alert('son');
            }, true);
    
            var father = document.querySelector('.father');
            // 给father注册单击事件,第3个参数为true
            father.addEventListener('click', function() {
                alert('father');
            }, true);
    
            // 给document注册单击事件,第3个参数为true
            document.addEventListener('click', function() {
                alert('document');
            }, true)
        </script>
    </body>
    
    </html>
    
  • 相关阅读:
    【Linux高级驱动】如何分析并移植网卡驱动
    【Linux高级驱动】网卡驱动分析
    【Linux高级驱动】I2C驱动框架分析
    【Linux高级驱动】触摸屏工作原理与工作流程
    【Linux高级驱动】触摸屏驱动的移植
    【Linux高级驱动】input子系统框架
    【Linux高级驱动】平台设备驱动机制的编程流程与编译进内核
    【Linux高级驱动】rtc驱动开发
    【Linux高级驱动】linux设备驱动模型之平台设备驱动机制
    【Linux】Linux基本命令扫盲
  • 原文地址:https://www.cnblogs.com/jianjie/p/12175768.html
Copyright © 2011-2022 走看看