zoukankan      html  css  js  c++  java
  • 事件冒泡

    事件冒泡

     一.事件流概念

    流是一种生动体现。用术语说流是对输入输出设备的抽象。以程序的角度说,流是具有方向的数据。

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

    在浏览器发展的过程中,开发团队遇到了一个问题。那就是页面中的哪一部分拥有特定的事件?

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

    通俗说,事件流所描述的就是从页面中接受事件的顺序。

    因为有两种观点,所以事件流也有两种,分别是事件冒泡和事件捕获。现主流是事件冒泡。

    事件冒泡

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

    下面写个例子:

    复制代码
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4   <meta charset="UTF-8">
     5   <title>Event Bubbling</title>
     6 </head>
     7 <body>
     8   <button id="clickMe">Click Me</button>
     9 </body>
    10 </html>
    复制代码

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

    复制代码
     1 var button = document.getElementById('clickMe');
     2 
     3 button.onclick = function() {
     4   console.log('1. You click Button');
     5 };
     6 document.body.onclick = function() {
     7   console.log('2. You click body');
     8 };
     9 document.onclick = function() {
    10   console.log('3. You click document');
    11 };
    12 window.onclick = function() {
    13   console.log('4. You click window');
    14 };
    复制代码

    在Chrome浏览器运行:

    如果点击了button,那么这个点击事件会按如下的顺序传播

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

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

     

    事件捕获

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

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

    事件阶段(Event Phases)

    当一个DOM事件触发时,它不是在触发的对象上只触发一次的,而是经历三个阶段。分别为

    1:一开始从文档的根节点流向目标对象(捕获阶段)

    2:然后在目标对向上被触发(目标阶段)

    3:之后再回溯到文档的根节点(冒泡阶段).

    1. 事件捕获阶段

    事件的第一个阶段是捕获阶段。事件从文档的根节点出发,随着DOM树的结构向事件的目标节点流去。途中经过各个层次的DOM节点,并在各节点上触发捕获事件,直到到达事件的目标节点。捕获阶段的主要任务是建立传播路径,在冒泡阶段,事件会通过这个路径回溯到文档跟节点。当事件发生时,首先发生的是事件捕获,为父元素截获事件提供了机会。
    例如,我把上面的Demo中,window点击事件更改为使用事件捕获模式。(addEventListener最后一个参数,true则代表使用事件捕获模式,false则表示使用事件冒泡模式。不理解的可以去学习一下addEventListener函数的使用)

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

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

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

     

    处于目标与事件冒泡阶段

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

     

    阻止事件冒泡

    事件冒泡过程,是可以被阻止的。防止事件冒泡而带来不必要的错误和困扰。
    这个方法就是:stopPropagation()
    我们对button的click事件做一些改造。

    1 button.addEventListener('click', function(event) {
    2   // event为事件对象
    3   console.log('1. You click Button');
    4   event.stopPropagation();
    5   console.log('Stop Propagation!');
    6 }, false);

     点击后,效果如下图:

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

     

    总结

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

    分有事件冒泡与事件捕获两种。


    DOM事件流的三个阶段:

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

     

    转载于刘彦佐“面试整理之DOM事件阶段”一文

     

     

  • 相关阅读:
    codeforces 19B Checkout Assistant DP
    bzoj1053: [HAOI2007]反素数ant [搜索]
    【2017泉州基地校集训】雷神领域[二分图][并查集]
    bzoj1433: [ZJOI2009]假期的宿舍 [二分图][二分图最大匹配]
    bzoj 1059: [ZJOI2007]矩阵游戏 [二分图][二分图最大匹配]
    二分图带权匹配-Kuhn-Munkres算法模板 [二分图带权匹配]
    luogu P1332 血色先锋队[bfs]
    匈牙利算法dfs模板 [二分图][二分图最大匹配]
    【2017泉州基地校集训】最优排名[贪心]
    最大流Dinic算法的一些优化 [网络流][最大流]
  • 原文地址:https://www.cnblogs.com/hewasdrunk/p/7380837.html
Copyright © 2011-2022 走看看