之前对事件模型还是比较清楚的,许多概念都清晰映射在脑海中。工作之后,一方面使用的局限性,二是习惯于用框架中的各种事件监听方式,简单即方便,久而久之,事件的一些概念开始淡出记忆中,就像我现在已经开始淡忘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();

JS的事件模型的更多相关文章

  1. js实现事件模型bind与trigger

    function Emitter() { this._listener = [];//_listener[自定义的事件名] = [所用执行的匿名函数1, 所用执行的匿名函数2] } //注册事件 Em ...

  2. js二级事件模型的处理细节

    一.纠正网络上的一个误传--“IE不支持事件捕获” 可以在浏览器中运行上面demo,在各主流浏览器中,鼠标移上都可以分别触发捕获与冒泡事件的监听函数,所以IE也是支持事件捕获的,连IE6都支持,只是在 ...

  3. js 事件模型详解

    把js的事件模型,分为两类,DOM0级和DOM2级, DOM0级 通常直接在DOM对象上绑定函数对象,指定事件类型,dom.onClick = function(){};类似于这种写法,移除事件,则直 ...

  4. js的事件学习笔记

    目录 0.参考 1.事件流 冒泡传播 事件捕获 2.事件绑定--onclick接口 onclick类的接口,只能注册一个同类事件 onclick类的接口,使用button.onclick = null ...

  5. JS事件模型小结

    三种事件模型:原始事件模型(DOM0),DOM2事件模型,IE事件模型: 不同点: 事件程序的注册(给HTML元素所对应的JS对象绑定事件) 事件传播的过程 事件模型的注册: 一.原始事件模型(没有兼 ...

  6. JS的事件绑定、事件流模型

    .t1 { background-color: #ff8080; width: 1100px; height: 40px } 一.JS事件 (一)JS事件分类 1.鼠标事件:click/dbclick ...

  7. javascript中0级DOM和2级DOM事件模型浅析 分类: C1_HTML/JS/JQUERY 2014-08-06 15:22 253人阅读 评论(0) 收藏

    Javascript程序使用的是事件驱动的设计模式,为一个元素添加事件监听函数,当这个元素的相应事件被触发那么其添加的事件监听函数就被调用: <input type="button&q ...

  8. 深入理解JS的事件绑定、事件流模型

     一.JS事件 (一)JS事件分类 1.鼠标事件: click/dbclick/mouseover/mouseout 2.HTML事件: onload/onunload/onsubmit/onresi ...

  9. js事件模型与自定义事件

    JavaScript 一个最简单的事件模型,需要有事件绑定与触发,还有事件删除. var eventModel = { list: {}, bind: function () { var args = ...

随机推荐

  1. springmvc4开发rest

    Spring MVC 4 RESTFul Web Services CRUD Example+RestTemplate Created on:  August 11, 2015  | Last upd ...

  2. Angular UI框架 Ng-alain @delon的脚手架的生成开发模板

    前言 首先感谢下 cipchk基于 Ng-Zorror 框架上制作的ng-alain . 之前很早就关注了 ng-alain,今天得空折腾了下. 折腾的时候发现官方文档有些坑,没有写清楚,所以我作为一 ...

  3. EasyUI datagrid动态生成列

    任务描述:根据用户选择时间段,生成列数据,如图

  4. 彻底理解了call()方法,apply()方法和bind()方法

    javascript中的每一个作用域中都有一个this对象,它代表的是调用函数的对象.在全局作用域中,this代表的是全局对象(在web浏览器中指的是window).如果包含this的函数是一个对象的 ...

  5. MySQL 5.7 新特性之初始化

    1. 把二进制安装包下载放在/opt 目录下并解压 2. 创建软连接, 并添加运行环境 ln -s /usr/local/mysql /opt/mysql-5.7.18-linux-glibc2.5- ...

  6. C# Hex编码和解码

    /// 从字符串转换到16进制表示的字符串 /// 编码,如"utf-8","gb2312" /// 是否每字符用逗号分隔 public static stri ...

  7. 如何让服务端同时支持WebSocket和SSL加密的WebSocket(即同时支持ws和wss)?

    自从HTML5出来以后,使用WebSocket通信就变得火热起来,基于WebSocket开发的手机APP和手机游戏也越来越多.我的一些开发APP的朋友,开始使用WebSocket通信,后来觉得通信不够 ...

  8. 【PYTHON】三级菜单

    # Author: Stephen Yuan area_range = { '广东省': { '广州市': { '海珠区': ['全区总面积90.40平方公里', '2015年,海珠区生产总值达到14 ...

  9. Hello——Java10新特性,请了解一下

    2018年3月20日,Java 10 正式发布! 相关地址: 官方地址:http://www.oracle.com/technetwork/java/javase/downloads/index.ht ...

  10. OpenShift实战(五):OpenShift容器监控Metrics

    1.创建持久化metric pv卷 [root@master1 pv]# cat metrics.json apiVersion: v1 kind: PersistentVolume metadata ...