zoukankan      html  css  js  c++  java
  • DOM中的事件傳播機制

      要講到事件傳播機制之前,首先要瞭解的是 什麼是事件?

      事件,發生在靜態頁面與動態行為之間的交互行為。是JavaScript 和 HTML的交互是通过事件实现的。比如,按鈕的點擊,鼠標的滑過,鍵盤的輸入等由鍵盤,鼠標行為引起的一連串的“多米諾反應”。這一反應就形成了事件流。

      事件流分兩部分:

        ①事件冒泡:

              

         從具體的“div”對象到最外層不具體的Document等任意外層元素包涵體。

        ②事件捕獲;

              

         捕獲,是從最外層元素一直追溯到具體的元素上,追本溯源的執著!!

        那麼,完整的事件流就是事件捕獲+事件冒泡+處於目標事件執行的函數行為!

        不同瀏覽器對於事件流的支持:

        一種說法是:

          Opera、Firefox、Sarfari都支持DOM事件流,IE不支持事件流,只支持时间冒泡。

        另一種說法是:

          IE:它认为事件流应该是事件冒泡。
          Netscape:它则认为事件流应该是事件捕获。
          W3C:首先是事件捕获然后事件冒泡。

      

    事件传播机制

    当一个事件发生以后,它会在不同的DOM节点之间传播(propagation)。这种传播分为三个阶段:


     
     
    • 第一阶段:从window对象传导到目标节点,称为“捕获阶段”(capture phase)。
    • 第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。
    • 第三阶段:从目标节点传导回window对象,称为“冒泡阶段”(bubbling phase)。
      这种三阶段的传播模型,会使得一个事件在多个节点上触发。
      比如:
    <div>
        <p>Click Me</p>
    </div>
    

    如果对这两个节点的click事件都设定监听函数,则click事件会被触发四次。<div><p>节点的捕获阶段和冒泡阶段各一次:

    1. 捕获阶段:事件从<div><p>传播时,触发<div>click事件;
    2. 目标阶段:事件从<div>到达<p>时,触发<p>click事件;
    3. 目标阶段:事件离开<p>时,触发<p>click事件;
    4. 冒泡阶段:事件从<p>传回<div>时,再次触发<div>click事件。

    用户点击网页的时候,浏览器总是假定click事件的目标节点,就是点击位置的嵌套最深的那个节点。所以<p>节点的捕获和冒泡阶段都会显示为target阶段。

    event.stopPropagation()

    stopPropagation方法阻止事件在DOM中继续传播,即取消进一步的事件捕获或冒泡,防止再触发定义在别的节点上的监听函数,但是不包括在当前节点上新定义的事件监听函数。
    我们可以在button的事件处理程序中调用stopPropagation()从而避免注册在body上的事件发生。

    var handler = function(e){
        alert(e.type);
        e.stopPropagation();
    }
    addEvent(document.body, 'click', function(){alert('Clicked body')});
    var btnClick = document.getElementById('btnClick');
    addEvent(btnClick, 'click', handler);
    //若是注释掉e.stopPropagation();在点击button的时候,由于事件冒泡,body的click事件也会触发,但是调用后这句后,事件会停止传播。
    

    event.preventDefault()

    preventDafault方法取消浏览器对当前事件的默认行为,比如点击链接后,浏览器跳转到指定页面,或者按一下空格键,页面向下滚动一段距离。该方法生效的前提是,事件的cancelable属性为true如果为fales,则调用该方法没有任何效果。
    该方法不会阻止事件的进一步传播(stopPropagation方法可用于这个目的)。只要在事件的传播过程中使用了preventDefault方法,该事件的默认方法就不会执行。

    //html代码为
    //<input type="checkbox" id="my-checkbox"/>
    
    var cb = document.getElementById('my-checkbox');
    cb.addEventListener('click', function(e){
        e.preventDafault();
    },);
    

    上面代码为点击单选框事件,设置监听函数,取消默认行为。由于浏览器的默认行为是选中单选框,所以这段代码会导致无法选中单选框。
    利用这个方法,可以为文本输入框设置校验条件。如果用户的输入不符合条件,就无法将字符输入文本框。

    function checkName(e){
        if(e.charCode < 97 || e.charCode > 122){
            e.preventDafault();
        }
    }
    //keypress监听函数,只能输入小写字母,否则输入事件的默认事件(写入文本框)将本取消。
    

    如果监听函数最后返回布尔值false(return false),浏览器也不会触发默认行为,与preventDafault方法有等同效果。

    事件代理

    由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理
    定义:事件代理就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。(delegation)。

    var ul = document.querySelector('ul');
    ul.addEventListener('click', function(event){
        if(event.target.tagName.toLowerCase() === 'li'){
            //...
        }
    })
    

    上面代码的click事件的监听函数定义在<ul>节点,但是实际上,它处理的是子节点<li>click事件。这样的好处是,只要定义一个监听函数,就能处理多个子节点的事件,且以后再添加子节点,监听函数依然有效。




    本文轉載于https://www.jianshu.com/p/1eb41968c8e3


       


      
      

      

      

  • 相关阅读:
    1641. 统计字典序元音字符串的数目
    1688. 比赛中的配对次数
    核心思路
    面试题 16.17. 连续数列
    70. 爬楼梯
    面试题 08.01. 三步问题
    剑指Offer 42. 连续子数组的最大和
    设计模式之原型模式
    代理模式之动态代理
    设计模式之禅(六大设计原则)
  • 原文地址:https://www.cnblogs.com/zhangdzz/p/10492406.html
Copyright © 2011-2022 走看看