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();
JS的事件模型的更多相关文章
- js实现事件模型bind与trigger
function Emitter() { this._listener = [];//_listener[自定义的事件名] = [所用执行的匿名函数1, 所用执行的匿名函数2] } //注册事件 Em ...
- js二级事件模型的处理细节
一.纠正网络上的一个误传--“IE不支持事件捕获” 可以在浏览器中运行上面demo,在各主流浏览器中,鼠标移上都可以分别触发捕获与冒泡事件的监听函数,所以IE也是支持事件捕获的,连IE6都支持,只是在 ...
- js 事件模型详解
把js的事件模型,分为两类,DOM0级和DOM2级, DOM0级 通常直接在DOM对象上绑定函数对象,指定事件类型,dom.onClick = function(){};类似于这种写法,移除事件,则直 ...
- js的事件学习笔记
目录 0.参考 1.事件流 冒泡传播 事件捕获 2.事件绑定--onclick接口 onclick类的接口,只能注册一个同类事件 onclick类的接口,使用button.onclick = null ...
- JS事件模型小结
三种事件模型:原始事件模型(DOM0),DOM2事件模型,IE事件模型: 不同点: 事件程序的注册(给HTML元素所对应的JS对象绑定事件) 事件传播的过程 事件模型的注册: 一.原始事件模型(没有兼 ...
- JS的事件绑定、事件流模型
.t1 { background-color: #ff8080; width: 1100px; height: 40px } 一.JS事件 (一)JS事件分类 1.鼠标事件:click/dbclick ...
- javascript中0级DOM和2级DOM事件模型浅析 分类: C1_HTML/JS/JQUERY 2014-08-06 15:22 253人阅读 评论(0) 收藏
Javascript程序使用的是事件驱动的设计模式,为一个元素添加事件监听函数,当这个元素的相应事件被触发那么其添加的事件监听函数就被调用: <input type="button&q ...
- 深入理解JS的事件绑定、事件流模型
一.JS事件 (一)JS事件分类 1.鼠标事件: click/dbclick/mouseover/mouseout 2.HTML事件: onload/onunload/onsubmit/onresi ...
- js事件模型与自定义事件
JavaScript 一个最简单的事件模型,需要有事件绑定与触发,还有事件删除. var eventModel = { list: {}, bind: function () { var args = ...
随机推荐
- CentOS ping www.baidu.com 报错 name or service not know
今天尝试安装了centos系统 玩一玩 刚刚装好的操作系统 ping www.baidu.com的时候 报出 name or service not known 查了好多资料,都没有很好的解决 最后 ...
- Paper藐小之处明察秋毫故时有物外之趣
暂且针对第一篇叶脉提取的paper 插入图像的"图 N": 英 Times New Roman, 中 宋体, 10磅. 文末的引文: 两端对齐. 流程图框格内文字换行时, 忌: 将 ...
- win10下 github+hexo搭建个人博客.md
我的博客地址 https://chenxianfu.github.io/ 遇到的坑 hexo 问题 4000端口打不开,可能端口占用,请输入一下命令 hexo server -p 4001 针对很多人 ...
- ES6 new syntax of let and const (one)
variable declarations : let, const,and block scope why we redefine the way about declarations? funct ...
- [LeetCode] Find the Closest Palindrome 寻找最近的回文串
Given an integer n, find the closest integer (not including itself), which is a palindrome. The 'clo ...
- Linux提示字符设置
当我们登陆linux后,显示的提示字符究竟是什么意思呢?又可不可以设置呢. 首先来看看默认的显示: 普通用户: [fuwh@localhost ~]$ root用户: [root@localhost ...
- [UOJ 12]猜数
Description
- [HNOI2003]消防局的设立
题目描述 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状 ...
- [HNOI2005]狡猾的商人
题目描述 输入输出格式 输入格式: 从文件input.txt中读入数据,文件第一行为一个正整数w,其中w < 100,表示有w组数据,即w个账本,需要你判断.每组数据的第一行为两个正整数n和m, ...
- ●CodeForces 698C LRU
题链: http://codeforces.com/problemset/problem/698/C题解.1: 概率dp,状压dp 棒棒哒题解:https://www.cnblogs.com/liu- ...