• [JS]笔记12之事件机制--事件冒泡和捕获--事件监听--阻止事件传播


    -->事件冒泡和捕获
    -->事件监听
    -->阻止事件传播

    一、事件冒泡和捕获

    1、概念:当给子元素和父元素定义了相同的事件,比如都定义了onclick事件,点击子元素时,父元素的onclick事件也会被触发。js里称这种事件连续发生的机制为事件冒泡或者事件捕获。
    IE浏览器:事件从里向外发生,事件从最精确对象(target)开始触发,然后到最不精确的对象(document)触发,即事件冒泡

    Netscape:事件从外向里发生,事件从最不精确的对象(document)开始触发,然后到最精确对象(target)触发,
    事件捕获


    2、W3C标准将两者进行中和,在任何的W3C的事件模型中,
    事件先进入捕获阶段,再进入冒泡阶段

    3、一般的绑定事件方式
    div1.onclick=function () {
    alert('div被点击');
    };
    在一个支持W3C DOM的浏览器中,一般的绑定事件方式,采用的是事件冒泡方式

    程序员可以选择绑定事件时采用事件捕获还是事件冒泡,
    办法就是绑定事件时通过addEventListener( )方法


    二、事件监听

    1、支持W3C标准的浏览器在绑定事件时可以用addEventListener(type,fn,useCapture) 方法
    参数:type----------事件类型,例:click
       fn--------------事件处理函数
       useCapture----布尔值true或false
    ( true表示事件捕获,false表示事件冒泡 )
    为了兼容浏览器,第三个参数一般设置为false

    事件监听:addEventListener(type,fn,useCapture) 

    事件移除:removeEventListener(type, fn, useCapture)

    2、因为IE678只支持事件冒泡,不支持事件捕获,所以它也不支持addEventListener( )方法,IE提供了另一个函数:

    attachEvent( type , fn )
    参数:type---------事件类型,例:onclick
       fn-------------事件处理函数
    没有第三个参数

    事件监听:attachEvent( type , fn )

    事件移除:detachEvent( type , fn )

    三、阻止事件传播

    事件冒泡事件捕获都有传播的特征
    阻止事件传播的方法:
    在W3C中使用 Event.stopPropagation();
    在IE中使用 Event.cancelBubble=true;

    var Event=ev||window.event;
    if (Event.stopPropagation){
    Event.stopPropagation();//非IE阻止事件传播
    }else{
    Event.cancelBubble=true;//IE阻止事件冒泡
    }

    四、阻止默认事件

    var Event=ev||event;
    if (Event.preventDefault) {
    Event.preventDefault(); //非IE阻止默认事件
    } else{
    Event.returnValue=false; //IE阻止默认事件
    };

    return false; 代码中遇到立即停止执行,跳出正在执行的函数,相当于终止符,可以用来阻止默认事件
    PS:注意使用位置,不能滥用

    五、代码

    组织事件传播示例:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4 <meta charset="UTF-8">
     5 <title>阻止事件传播</title>
     6 <style>
     7 *{margin:0;padding:0;list-style: none;}
     8 ul{500px;height:300px;background: #ccc;}
     9 li{300px;height:150px;background: pink;}
    10 p{100px;height:100px;background:blue;}
    11 </style>
    12 </head>
    13 <body>
    14     <ul>
    15         <li>
    16             <p></p>
    17         </li>
    18     </ul>
    19 <script>
    20     var ul=document.getElementsByTagName('ul')[0];
    21     var li=document.getElementsByTagName('li')[0];
    22     var p=document.getElementsByTagName('p')[0];
    23     ul.onclick=function(){
    24         alert('我是ul');
    25     }
    26     li.onclick=function(ev){
    27         alert('我是li');
    28         var e=window.event||ev;
    29         if (e.stopPropagation) {//组织事件传播到父级
    30             e.stopPropagation();
    31             //非IE阻止事件传播(W3C)
    32         } else {
    33             e.cancelBubble=true;
    34             //IE阻止事件传播(IE)
    35         }
    36     }
    37     p.onclick=function(){
    38         alert('我是p');
    39     }
    40 
    41 </script>
    42 </body>
    43 </html>

    自定义右击菜单练习:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4 <meta charset="UTF-8">
     5 <title></title>
     6 <style>
     7 *{margin:0;padding:0;}
     8 div{150px;height:300px;background: pink;display:none;position: absolute;}
     9 span{color:red;}
    10 </style>
    11 </head>
    12 <body>
    13 <div>
    14     <span>第一页</span>
    15     <span>下一页</span>
    16     <span>刷新</span>
    17 </div>
    18 <script>
    19     var div=document.getElementsByTagName('div')[0];
    20     document.oncontextmenu=function(ev){//菜单右击事件
    21         div.style.display='block';
    22         var e=window.event||ev;
    23         if(e.preventDefault){//组织默认右击事件
    24             e.preventDefault();
    25         }else{
    26             e.returnValue=false;
    27         }
    28         var winH=document.documentElement.clientHeight;
    29         var winW=document.documentElement.clientWidth;
    30         var divH=div.offsetHeight;
    31         var divW=div.offsetWidth;
    32         var x=e.clientX;
    33         var y=e.clientY;
    34         if (winH-y<divH) {
    35             div.style.top=(y-divH)+'px';
    36         } else {
    37             div.style.top=y+'px';
    38         }
    39         if (winW-x<divW) {
    40             div.style.left=(x-divW)+'px';
    41         } else {
    42             div.style.left=x+'px';
    43         }
    44         
    45     }
    46 </script>
    47 </body>
    48 </html>
  • 相关阅读:
    MSSQL 2012 密钥
    同台同时多开DELPHI2007的解决办法
    DELPHI快捷键
    Delphi编码规范
    解决Delphi 2010启动时卡死并报“displayNotification: 堆栈溢出”错误
    Test
    sched python 定时任务
    springboot2.x 整合redis
    springboot 忽略null属性值,不传递
    logback.xml 配置使用
  • 原文地址:https://www.cnblogs.com/paulirish/p/bubbleandpropagation.html
Copyright © 2020-2023  润新知