zoukankan      html  css  js  c++  java
  • JS的事件模型

      之前对事件模型还是比较清楚的,许多概念都清晰映射在脑海中。工作之后,一方面使用的局限性,二是习惯于用框架中的各种事件监听方式,简单即方便,久而久之,事件的一些概念开始淡出记忆中,就像我现在已经开始淡忘C语言的指针、麦克斯韦方程组、矩阵的变换、最小二乘法等。知识就像五彩缤纷的鹅卵石铺垫在你前行的道路上,从简单到深刻,从深刻到领悟,一直 助你渐行渐远。回头看看事件模型呗。


    一、事件简介

    说到事件,大家可以很快想到很多事件类型,比如:
    鼠标事件
    键盘事件
    框架事件 onerror onresize onscroll等
    表单事件事件 onblur onfocus等
    剪贴板事件 oncopy oncut onpaste
    打印事件 onafterprint onbeforeprint
    拖动事件 ondrag ondragenter等
    media事件 onplay onpause
    动画事件 animationend

    UI事件:load 、unload、error、select、resize、scroll

    二、事件的三种模型


    1、原始事件模型(DOM0级)
      特点:原始事件模型中,事件发生后没有传播的概念,没有事件流。事件发生,立即处理。
    监听函数只是元素的一个属性值,通过指定元素的属性值来绑定监听器。书写方式有两种:

      HTML: <input id=”btn” onclick=”func()” />
    js : document.getElementsById(‘btn’).onclick = func

      优点:所有浏览器都兼容

      缺点:
    a、逻辑与显示没有分离;
    b、相同事件的监听函数只能绑定一个,后绑定的会覆盖掉前面的。
    c、无法通过事件的冒泡、委托等机制等。

      在当前web程序模块化开发以及更加复杂的逻辑状况下,这种方式显然已经落伍了,所以在真
    正项目中不推荐使用,平时写点demo倒是可以,速度比较快。

    2、IE事件模型
    特点:IE是将event对象在处理函数中设为window的属性,一旦函数执行结束,便被置为null
    了。
    IE的事件模型只有两步,先执行元素的监听函数,然后事件沿着父节点一直冒泡到document。
    绑定解除监听函数的方法:
    attachEvent( "eventType","handler"),其中evetType为事件的类型,如onclick,注意要加
    ’on’。
    解除事件监听器的方法是 detachEvent("eventType","handler" );
    缺点:就是只能IE自己用,太高冷了。

    说明:

      a、IE中不支持事件捕获,只有事件冒泡。

      b、使用attachEvent()方法时候,事件处理程序会在全局作用域中运行,因此this等于window。这点在编写跨浏览器代码时候很重要。

      c、添加多个事件的时候,触发的顺序是:后添加的先执行,这点和DOM方法不同。

      d、最好不要添加匿名的函数作为执行的函数,这样事件无法被移除。DOM也要注意这个问题,因为:

     var btn = document.getElementById('myBtn');
       //添加
       btn.attachEvent("onclcik",function(){
       	  dosomthing();
       });
        
       //移除  !!无法移除,因为两个匿名函数压根不一样 所以把事件写成handler的形式
       btn.detachEvent("onclcik",function(){
       	  dosomthing();
       });
    

      

    3、 DOM2事件模型
    在 W3C 2 级 DOM 事件中规范了事件模型,即 DOM2事件模型。现代浏览器(IE9以下不算)都遵
    循了这个规范。
    特点:
    W3C制定的事件模型中,一次事件的发生包含三个过程:
      a、事件捕获阶段。事件被从document一直向下传播到目标元素,在这过程中依次检查经过的节
              点是否注册了该事件的监听函数,若有则执行。
      b、事件处理阶段。事件到达目标元素,执行目标元素的事件处理函数.
      c、事件冒泡阶段。事件从目标元素上升一直到达document,同样依次检查经过的节点是否注册
    了该事件的监听函数,有则执行。

       注意:所有的事件类型都会经历事件捕获阶段,但是只有部分事件会经历事件冒泡阶段,例如
    submit事件就不会被冒泡。为了最大程度兼容各种浏览器,一般都是将事件处理函程序添加到事件流的冒泡阶段。

    绑定解除监听函数的方法:
    addEventListener("eventType","handler","true|false");其中eventType指事件类型,注意
    不要加‘on’前缀,与IE下不同。
    第二个参数是处理函数,
    第三个即用来指定是否在捕获阶段进 true捕获阶段 false 只有冒泡阶段
    监听器的解除也类似:removeEventListner("eventType","handler","true!false");


    兼容IE和现代浏览器的事件注册监听写法

    var a = document.getElementById('XXX');
    if(a.attachEvent){
        a.attachEvent('onclick',func);
    }
    else{//IE9以上和主流浏览器
        a.addEventListener('click',func,false);
    }

    现有的框架和类库都会对适应各种浏览器做兼容性的封装,JQuery底层即使用了上面的兼容性写法。

    三、事件的捕获-冒泡机制
    DOM2标准中,一次事件的完整过程包括三步:捕获→执行目标元素的监听函数→冒泡,在捕获和
    冒泡阶段,会依次检查途径的每个节点,如果该节点注册了相应的监听函数,则执行监听函数。

    以如下HTML结构为例子,执行流程应该是这样的:

    <div id="parent">
           父元素
           <div id="child">子元素</div>
    </div>

    运行一下一目了然。

    var parent= document.getElementById('parent');
    	console.dir(parent);
        var child = document.getElementById('child');
        parent.addEventListener('click',function(){alert('父亲在捕获阶段被点
    
    击');},true);//第三个参数为true
        child.addEventListener('click',function(){alert('孩子被点击了');},false);
     parent.addEventListener('click',function(){alert('父亲在冒泡阶段被点击
    
    了');},false);//第三个参数为false
    

     

      可以看到,第三个即用来指定是否在捕获阶段进 true捕获阶段,false没有捕获阶段 。
    如果不想让事件向上冒泡,可以在监听函数中调用event.stopPrapagation()来完成,后面会有应
    用的栗子。

    四、事件对象

      触发在DOM上的某个事件时,会产生一个事件对象event,这个对象包含了与事件有关的信息。所有浏览器都支持事件对象,主要分为:

    1、DOM中的事件对象

    兼容DOM的浏览器会将一个事件对象传到事件处理程序中。event对象包含了与创建它的特定事件有关的属性和方法,一般都不太一样,但也有些相同的成员。比如

    bubbles:表明事件是否冒泡

    currentTarget:事件处理程序当前正在处理的事件的那个元素

    target:事件的目标,与currentTarget还不太一样。

    preventDefault() :取消事件的默认行为,比如点击a标签默认跳转链接,点击button默认提交

    stopPropagation():取消事件进一步捕获或者冒泡,经常会用到

    注意:

    只有在事件处理程序执行期间,event对象才会存在;一旦事件处理程序执行完毕,event对象就会被销毁。

    2、IE中的事件对象

    与访问DOM中的event对象不同,访问IE中的event对象有几种不同的方式。

    在DOM0级方法中,envet对象作为Window对象的一个属性存在。

    注意:

      a、在IE中,window.event.returnValue = false;相当于DO中的preventDefault();

      b、stopPropagation()方法是一样的。

      c、IE中的event.srcElement相当于DOM中的event.target

    五、事件委托机制

      委托就是把事件监听函数绑定到父元素上,让它的父辈来完成事件的监听,这样就把事情“委托
    ”了过去。在父辈元素的监听函数中,可通过event.target属性拿到触发事件的原始元素,然后
    再对其进行相关处理。

     

    六、jQuery中的事件监听方式
      jQuery中提供了四种事件监听方式,分别是bind、live、delegate、on,对应的解除监听的
    函数分别是unbind、die、undelegate、off。这几个方法已经对各种浏览器的兼容性进行封装。
    具体方法可以查看手册。
    注意几点:
    jQuery推荐事件的绑定都使使用on方法
    jQuery默认事件不在捕获中进行

    七、什么是自定义事件
    张鑫旭的《js-dom自定义事件》


    八、一个简单例子
    点击弹窗之外任何地方,弹框关闭。


    方法:给body绑定事件,在事件的执行函数里关闭弹框;
    给弹框元素绑定点击事件,在事件的执行函数里面组织事件冒泡,即:
    event.stopPrapagation();

  • 相关阅读:
    【转贴】Render to Texture(渲染到纹理)
    【转贴】EffectFramework
    真正的电脑高手
    【ZT】剑道与编程之道
    【转贴】DXUT 框架入门 2
    【转贴】DXUT 框架函数介绍
    第四章 治病法要(1)
    第一章 略说中医的学习与研究(5)
    第二章 伤寒之意义(2)
    第一章 略说中医的学习与研究(4)
  • 原文地址:https://www.cnblogs.com/leaf930814/p/6980501.html
Copyright © 2011-2022 走看看