zoukankan      html  css  js  c++  java
  • js事件详解

    事件流
    DOM事件流的三个阶段:1、事件捕获阶段 2、处于目标阶段 3、事件冒泡阶段
    要理解事件流我们先来看一看事件的整个传播过程:
      事件捕获阶段:用户触发事件window-->document-->html-->body-->祖先节点-->.......-->父节点-->目标元素
      事件冒泡阶段:目标元素-->父节点-->......->祖先节点-->body-->html-->document-->window
    所有的浏览器都实现了事件冒泡(网景除外)。
    IE9+和所有的现代浏览器也都支持事件捕获并且是从window开始捕获的。
    NOTE:由于低版本IE(IE8-)不能实现事件捕获,因此很少用。
    事件处理程序
    响应某个事件的处理函数就是事件处理程序。
    1、html事件处理程序
    1 <input type="button" value="单击事件" oncick="fnHandler()" />

    NOTE:在html事件处理程序中使用双引号、大于、小于等符号时可以使用实体符代替。

    1 <button onclick="fnShow(&quot;hello&quot;)">单击事件</button>
    2 <script>
    3     function fnShow(sMsg){
    4         alert(sMsg);
    5     }
    6 </script>

    缺点:

      1、时差问题。当事件处理程序代码放在元素的后面,在事件处理程序没有解析完成用户就出发了事件就会报错;

      2、html代码和javascript代码耦合比较高。

    2、DOM0级事件处理程序

      将函数赋值给元素的事件处理程序属性

    1     var oBtn = document.getElementById('btn');
    2     oBtn.onclick = function(){
    3         alert('clicked');
    4     }

      删除DOM0级事件处理程序,就是将该事件处理属性设置为null。

    1     var oBtn = document.getElementById('btn');
    2     oBtn.onclick = function(){
    3         alert('clicked');
    4     }
    5     oBtn.onclick = null;

    3、DOM2级事件处理程序

      DOM2级事件处理程序提供了两个方法:addEventListener和removeEventListener。他们包含三个参数:事件名、事件处理函数、布尔值(true捕获、false冒泡).

    1     var oBtn = document.getElementById('btn');
    2     oBtn.addEventListener('click', function(){
    3         alert('clicked');
    4     }, false);

      好处:可以给同一个事件添加多个事件处理函数。

    1     var oBtn = document.getElementById('btn');
    2     oBtn.addEventListener('click', function(){
    3         alert('clicked');
    4     }, false);
    5     oBtn.addEventListener('click', function(){
    6         alert('clicking');
    7     }, false);

      通过addEventListener添加的事件处理程序只能通过removeEventListener来删除。

    NOTE:通过addEventListener添加的匿名函数不能被reomveEventListener删除。

    1     // 添加的和删除的不是同一个函数。在堆内存中不一样。
    2     var oBtn = document.getElementById('btn');
    3     oBtn.addEventListener('click', function(){
    4         alert('clicked'); // 任然会执行
    5     }, false);
    6     oBtn.removeEventListener('click', function(){
    7         alert('clicked');
    8     }, false);

    4、IE8-事件处理程序

      IE8-实现了DOM类似的两个事件处理方法:attachEvent()、detachEvent()。通过这两个方法只能添加事件到冒泡阶段。

    1     var oBtn = document.getElementById('btn');
    2     oBtn.attachEvent('onclick', function(){ // 事件名前要加on
    3         alert('clicked');
    4     });

    NOTE:使用attachEvent添加事件时的执行作用域是全局作用域。

    1     var oBtn = document.getElementById('btn');
    2     oBtn.attachEvent('onclick', function(){ 
    3         alert(this == window); // true
    4         alert('clicked');
    5     });
    6     oBtn.addEventListener('click', function(){
    7         alert(this == window); // false
    8         alert('clicked');
    9     }, false);

    NOTE:在IE9、10中任然保留了这两个方法并且可以和addEventListener叠加事件,不能相互删除对应事件,IE11+已经没有这两个方法了。

     1     var oBtn = document.getElementById('btn');
     2     oBtn.attachEvent('onclick', fnHandler); // 添加
     3     oBtn.removeEventListener('click', fnHandler, false); // 删除
     4     function fnHandler(){
     5         alert('clicked'); // 任然执行
     6     }
     7     oBtn.addEventListener('click', fnHandler1, false); // 添加
     8     oBtn.detachEvent('onclick', fnHandler1); // 删除
     9     function fnHandler1(){
    10         alert('clicked1'); // 任然执行
    11     }

    NOTE:attachEvent(先添加后执行)添加多个事件时与addEventListener(先添加先执行)事件执行顺序相反。在IE8-中是这样的,但是在IE9、10中却是先添加先执行。

     1     var oBtn = document.getElementById('btn');
     2     oBtn.attachEvent('onclick', function(){
     3         alert('attach1');
     4     });
     5     oBtn.attachEvent('onclick', function(){
     6         alert('attach2');
     7     });
     8 
     9     oBtn.addEventListener('click', function(){
    10         alert('add1');
    11     });
    12     oBtn.addEventListener('click', function(){
    13         alert('add2');
    14     });
    跨浏览器的事件处理程序实现
    首先检查DOM2级事件处理程序、再检测IE事件处理程序、最后通过DOM0级事件处理程序。
     1     var oBtn = document.getElementById('btn');
     2     var EventUtil = {
     3         addHandler: function(oDom, sEventType, fnHandler){
     4             if(oDom.addEndEventListener){
     5                 oDom.addEndEventListener(sEventType, fnHandler, false);
     6             }else if(oDom.attachEvent){
     7                 oDom.attachEvent('on' + sEventType, fnHandler);
     8             }else{
     9                 oDom['on' + sEventType] = fnHandler;
    10             }
    11         },
    12         removeHandler: function(oDom, sEventType, fnHandler){
    13             if(oDom.removeEndEventListener){
    14                 oDom.removeEndEventListener(sEventType, fnHandler, false);
    15             }else if(oDom.detachEvent){
    16                 oDom.detachEvent('on' + sEventType, fnHandler);
    17             }else{
    18                 oDom['on' + sEventType] = null;
    19             }
    20         }
    21     }
    跨浏览器的事件对象
     1     var EventUtil = {
     2         // 绑定事件
     3         addHandler: function(oDom, sEventType, fnHandler){
     4             if(oDom.addEndEventListener){
     5                 oDom.addEndEventListener(sEventType, fnHandler, false);
     6             }else if(oDom.attachEvent){
     7                 oDom.attachEvent('on' + sEventType, fnHandler);
     8             }else{
     9                 oDom['on' + sEventType] = fnHandler;
    10             }
    11         },
    12         // 解除事件
    13         removeHandler: function(oDom, sEventType, fnHandler){
    14             if(oDom.removeEndEventListener){
    15                 oDom.removeEndEventListener(sEventType, fnHandler, false);
    16             }else if(oDom.detachEvent){
    17                 oDom.detachEvent('on' + sEventType, fnHandler);
    18             }else{
    19                 oDom['on' + sEventType] = null;
    20             }
    21         },
    22         // 获取事件对象
    23         getEvent: function (event) {
    24             return event ? event : window.event;
    25         },
    26         // 获取事件目标元素
    27         getTarget: function(event){
    28             return event.target || event.srcElement;
    29         },
    30         // 阻止默认事件
    31         preventDefault: function(event){
    32             if(event.preventDefault){
    33                 event.preventDefault();
    34             }else{
    35                 event.returnValue = false;
    36             }
    37         },
    38         // 阻止事件冒泡
    39         stopPropagation: function(event){
    40             if(event.stopPropagation){
    41                 event.stopPropagation();
    42             }else{
    43                 event.cancelBubble = true;
    44             }
    45         }
    46     }
  • 相关阅读:
    【idea】批量修改文件的换行类型
    【shell】for循环执行sql语句
    【gitlab】创建token供外部git clone
    【idea】修改git源
    【浏览器】 NET::ERR_CERT_INVALID
    mac os 11 Big Sur 根目录无法写入解决办法
    dbeaver把表数据导出csv时字符串自动加双引号问题解决
    spring boot2 jpa分页查询百万级数据内存泄漏
    win10安装MAT并单独配置jdk11
    Transaction silently rolled back because it has been marked as rollback-only
  • 原文地址:https://www.cnblogs.com/tyxloveyfq/p/4294548.html
Copyright © 2011-2022 走看看