zoukankan      html  css  js  c++  java
  • 理解DOM事件流的三个阶段

    本文主要解决两个问题:
      1.什么是事件流
      2.DOM事件流的三个阶段

    事件流之事件冒泡与事件捕获

    在浏览器发展的过程中,开发团队遇到了一个问题。那就是页面中的哪一部分拥有特定的事件?
    可以想象画在一张纸上的一组同心圆,如果你把手指放在圆心上,那么你的手指指向的其实不是一个圆,而是纸上所有的圆。放到实际页面中就是,你点击一个按钮,事实上你还同时点击了按钮所
    有的父元素。 开发团队的问题就在于,当点击按钮时,是按钮最外层的父元素先收到事件并执行,还是具体元素先收到事件并执行?所以这儿引入了事件流的概念。

    事件冒泡


     

    事件冒泡即事件开始时,由最具体的元素接收(也就是事件发生所在的节点),然后逐级传播到较为不具体的节点。
    举个栗子,就很容易明白了。

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Event Bubbling</title>
    </head>
    <body>
      <button id="clickMe">Click Me</button>
    </body>
    </html>

    然后,我们给button和它的父元素,加入点击事件。 

    <script type="text/javascript"> 
            var button = document.getElementById('clickMe'); 
            button.onclick = function() {
              console.log('1. You click Button');
            };
            document.body.onclick = function() {
              console.log('2. You click body');
            };
            document.onclick = function() {
              console.log('3. You click document');
            }; 
            window.onclick = function() {
              console.log('4. You click window');
            };
    </script>

    效果如图:

    在代码所示的页面中,如果点击了button,那么这个点击事件会按如下的顺序传播(Chrome浏览器):

    1. button
    2. body
    3. document
    4. window

    也就是说,click事件首先在<button>元素上发生,然后逐级向上传播。这就是事件冒泡。

    事件捕获


     

    事件捕获的概念,与事件冒泡正好相反。它认为当某个事件发生时,父元素应该更早接收到事件,具体元素则最后接收到事件。比如说刚才的demo,如果是事件捕获的话,事件发生顺序会是这样的:

    1. window
    2. document
    3. body
    4. button
    5.  

    当然,由于时代更迭,事件冒泡方式更胜一筹。所以放心的使用事件冒泡,有特殊需要再使用事件捕获即可。

    DOM事件流


     

    DOM事件流包括三个阶段。 
        1.事件捕获阶段
        2.处于目标阶段
        3.事件冒泡阶段

    如图所示(图片源于网络,若侵权请告知):

    1. 事件捕获阶段

    也就是说,当事件发生时,首先发生的是事件捕获,为父元素截获事件提供了机会。
    例如,我把上面的Demo中,window点击事件更改为使用事件捕获模式。(addEventListener最后一个参数,为true则代表使用事件捕获模式,false则表示使用事件冒泡模式。不理解的可以去学习一下addEventListener函数的使用)

    window.addEventListener("click",function(){
                console.log('4. You click window');
            },true)

    此时,点击button的效果是这样的。

    可以看到,点击事件先被父元素截获了,且该函数只在事件捕获阶段起作用。

    2.处于目标与事件冒泡阶段

    事件到了具体元素时,在具体元素上发生,并且被看成冒泡阶段的一部分。
    随后,冒泡阶段发生,事件开始冒泡。

    3.阻止事件冒泡

    事件冒泡过程,是可以被阻止的。防止事件冒泡而带来不必要的错误和困扰。
    这个方法就是:stopPropagation()

    stopPropagation() 方法
    终止事件在传播过程的捕获、目标处理或起泡阶段进一步传播。调用该方法后,该节点上处理该事件的处理程序将被调用,事件不再被分派到其他节点。

    我们对button的click事件做一些改造。

    <script type="text/javascript"> 
            var button = document.getElementById('clickMe'); 
            button.addEventListener('click', function(event) { 
              console.log('1. You click Button');
              event.stopPropagation();
              console.log('Stop Propagation!');
            }, false);
            document.body.onclick = function() {
              console.log('2. You click body');
            };
            document.onclick = function() {
              console.log('3. You click document');
            }; 
            window.addEventListener("click",function(){
                console.log('4. You click window');
            },true)
    </script>

    不难看出,事件在到达具体元素后,停止了冒泡。但不影响父元素的事件捕获。

    总结与感想


     

    事件流:描述的就是从页面中接受事件的顺序。分有事件冒泡与事件捕获两种。
    DOM事件流的三个阶段:

      1. 事件捕获阶段
      2. 处于目标阶段
      3. 事件冒泡阶段

    原文链接: 寒假前端学习(10)——理解DOM事件流的三个阶段

  • 相关阅读:
    .Net自动生成Html新闻系统V1.0 Beta 下载
    Visual Studio .NET 2003中自己找到的一个小技巧[图]
    多表连接的SQL写法(SqlServer、Oracle)
    在线人数统计 V1.0(Asp.net+ SqlServer) 源码下载
    Visual Studio 2005安装后,原来的Asp.net1.1不能执行的解决方法。
    [函数]截取固定长的字符串(双字节的计2位)
    [原创]asp.net 2.0下的自定义树(myTreeView)
    通用的数据库操作助手类
    关于时间国际化的方案
    HTTPS Cipher Suite问题
  • 原文地址:https://www.cnblogs.com/hfxm/p/5535501.html
Copyright © 2011-2022 走看看