dom2事件级事件和dom0级事件区别吗

深入理解DOM事件机制系列第二篇——事件处理程序
来源:博客园
×
目录

前面的话
  事件处理程序又叫事件侦听器,实际上就是事件的绑定函数。事件发生时会执行函数中相应代码。事件处理程序有HTML事件处理程序、DOM0级事件处理程序、DOM2级事件处理程序和IE事件处理程序四类,下面将详细介绍该部分内容
 
HTML事件处理程序
  某个元素支持的每种事件,都可以使用一个与相应事件处理程序同名的HTML特性来指定。这个特性的值应该是能够执行的JavaScript代码
  在事件处理程序函数内部,this值等于事件的目标元素

&div id="box" style="height:30width:200background-color:"onclick = "this.innerHTML+= '1';"&&/div&


  在HTML中定义的事件处理程序也可以调用在页面其他地方定义的脚本

&div id="box" style="height:30width:200background-color:"onclick = "test()"&&/div&
&script&
function test(){box.innerHTML+= '1';}

&/script&


  HTML事件处理程序会创建一个封装着元素属性值的函数。这个函数中有一个局部变量event,也就是事件对象。通过event变量,可以直接访问事件对象,不用自己定义它,也不用从函数的参数列表中获取

&div id="box" style="height:30width:200background-color:"onclick = "this.innerHTML+= event."&&/div&


  在事件处理程序函数内部,可以像访问局部变量一样访问document及该元素本身的成员。如此一来,事件处理程序要访问自己的属性就简单多了

&button id="box" value="test" style="height:30width:200background-color:"onclick = "this.innerHTML+="&&/button&


【扩展】
  下列这种情况输出的是空字符串'',如果与预想结果不一致,请

&script&
var value=123;
&/script&
&button style="height:30width:200background-color:"onclick = "this.innerHTML+="&&/button&


缺点
【1】时差问题
  因为用户可能会有HTML元素一出现在页面上时就触发相应的事件,但当时的事件处理程序有可能尚不具备执行条件,就会报错

&button style="height:30width:200background-color:"onclick = "this.innerHTML+="&&/button&
&script src="/test.js"&&/script&
&script&
var val=123;
&/script&

【2】耦合问题
   客户端编程的通用风格是保持HTML内容和javaScript行为分离,所以应该避免使用HTML事件处理程序属性,因为这些属性直接混合了 javaScript和HTML,且不易扩展
 
DOM0级事件处理程序
  通过javaScript指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。这种为事件处理程序赋值的方法是在第四代Web浏览器中出现的,而且至今仍然为所有现代浏览器所支持。原因一是简单,二是具有跨浏览器的优势
  每个元素都有自己的事件处理程序属性,这些属性通常全部小写,将这种属性的值设置为一个函数,就可以指定事件处理程序
  [注意]以DOM0级方式添加的事件处理程序会在事件流的冒泡阶段被处理

&div id="box" style="height:30width:200background-color:"&&/div&
&script&
box.onclick = function(){this.innerHTML += '1';}

&/script&



  可以通过将事件处理程序属性设置为null来删除事件处理程序

box.onclick =

缺点
  DOM0级事件处理程序的缺点是围绕着每个事件目标对于每种事件类型只能添加一个事件处理程序
 
DOM2级事件处理程序
  DOM2级事件处理程序定义了两个方法用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener()
  所有DOM节点中都包含这两个方法,并且它们都接受3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后的布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。若最后的布尔值不填写,则和false效果一样
  [注意]IE8-浏览器不支持DOM2级事件处理程序
  使用DOM2级事件处理程序的好处是可以添加多个事件处理程序,并按照他们添加的顺序触发
  以下代码以1-2的顺序输出

&div id="box" style="height:30width:200background-color:"&&/div&
&script&
box.addEventListener('click',function(){this.innerHTML += '1'},false);
box.addEventListener('click',function(){this.innerHTML += '2'},false);

&/script&



  以下代码以2-1的顺序输出

&div id="box" style="height:30width:200background-color:"&&/div&
&script&
setTimeout(function(){
box.addEventListener('click',function(){this.innerHTML += '1'},false);

},16);
box.addEventListener('click',function(){this.innerHTML += '2'},false);

&/script&


移除
  通过addEventListener()添加的事件处理程序只能使用removeEventListener()来移除,移除时传入的参数与添加处理程序时使用的参数相同。这意味着,addEventListener()添加的匿名函数将无法移除  
  以下无效

&div id="box" style="height:30width:200background-color:"&&/div&
&script&
box.addEventListener("click",function(){
this.innerHTML += '1'
},false);
box.removeEventListener('click',function(){
this.innerHTML += '1'
},false);

&/script&


  以下有效

&div id="box" style="height:30width:200background-color:"&&/div&
&script&
var handle = function(){this.innerHTML += '1'};
box.addEventListener("click",handle,false);
box.removeEventListener('click',handle,false);

&/script&


IE事件处理程序
  IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。这两个方法接受相同的两个参数:事件处理程序名称与事件处理程序函数。由于IE8-浏览器只支持事件冒泡,所以通过attachEvent()添加的事件处理程序都会被添加到事件冒泡阶段
  attachEvent()方法的第一个参数是"onclick",而非DOM的addEventListener()方法中的"click"

&div id="box" style="height:30width:200background-color:"&&/div&
&script&
box.attachEvent('onclick',function(){this.innerHTML += '1';});
&/script&


   [注意]attachEvent()方法只冒泡到document,且IE10-浏览器支持

&div id="box" style="height:30width:200background-color:"&&/div&
&button id="reset"&还原&/button&
&script&
//IE10-浏览器返回div body html document
//其他浏览器报错
reset.onclick = function(){history.go();}
box.attachEvent('onclick',function(){box.innerHTML += 'div\n';});
document.body.attachEvent('onclick',function(){box.innerHTML += 'body\n';});
document.documentElement.attachEvent('onclick',function(){box.innerHTML += 'html\n';});
document.attachEvent('onclick',function(){box.innerHTML += 'document\n';});
window.attachEvent('onclick',function(){box.innerHTML += 'window\n';});
&/script&



this
  与其他三个事件处理程序不同,IE事件处理程序的this指向window,而非被绑定事件的元素

&!-- &div& --&
&div id="box" style="height:100width:300background-color:"
onclick = "console.log(this)"&&/div&


&div id="box" style="height:100width:300background-color:"&&/div&
&script&
box.onclick= function(){
console.log(this);//&div&
}
&/script&


&div id="box" style="height:100width:300background-color:"&&/div&
&script&
box.addEventListener('click',function(){
console.log(this);//&div&
});
&/script&


&div id="box" style="height:100width:300background-color:"&&/div&
&script&
box.attachEvent('onclick',function(){
console.log(this);//window
});
&/script&

顺序
  使用attachEvent()方法添加的事件处理程序的触发顺序是有区别的。IE9、10浏览器是按正序执行的,而IE8-浏览器则是按倒序执行的  

&div id="box" style="height:30width:100background-color:"&&/div&
&script&
box.attachEvent('onclick',function(){
box.innerHTML += '1';
});
box.attachEvent('onclick',function(){
box.innerHTML += '2';
});
&/script&


移除
  使用attachEvent()添加的事件可以通过detachEvent()来移除,条件是必须提供相同的参数。与DOM方法一样,这也意味着添加的匿名函数将不能被移除。不过,只要能够将对相同函数的引用传给detachEvent(),就可以移除相应的事件处理程序  
  以下无效

&div id="box" style="height:30width:200background-color:"&&/div&
&script&
box.attachEvent("onclick",function(){
box.innerHTML += '1'
},false);
box.detachEvent('onclick',function(){
box.innerHTML += '1'
},false);

&/script&

  以下有效

&div id="box" style="height:30width:200background-color:"&&/div&
&script&
var handle = function(){box.innerHTML += '1'};
box.attachEvent("onclick",handle,false);
box.detachEvent('onclick',handle,false);

&/script&


 
总结
  由于IE8-浏览器不支持addEventListener()方法,所以需要配合attachEvent()方法来实现全浏览器的事件绑定兼容写法。同时,由于attachEvent()方法中的this指向window,所以需要对this进行显式修改

function addEvent(target,type,handler){
if(target.addEventListener){
target.addEventListener(type,handler,false);
}else{
target.attachEvent('on'+type,function(event){
return handler.call(target,event);
}
}

调用顺序
  如果浏览器同时出现这四种事件处理程序,那么它们的调用顺序在各浏览器中表现并不一致 

&div id="box" style="height:100width:100background:" onclick = "this.innerHTML +='html\n'"&&/div&
&script&
if(box.addEventListener){
box.addEventListener('click',function(){this.innerHTML += 'DOM2级\n'})
}

if(box.attachEvent){
box.attachEvent('onclick',function(){box.innerHTML +='IE\n'})
}
box.onclick = function(){
this.innerHTML += 'DOM0级\n';
}
&/script&


【相同点】
  如果同时出现HTML事件处理程序和DOM0级事件处理程序,DOM0级会覆盖HTML事件处理程序
【不同点】
  chrome/opera/safari等webkit内核的浏览器会按照事件处理程序出现的顺序来排列,所以结果为:DOM2级 DOM0级
  firefox浏览器和IE浏览器会将DOM0级事件优先调用
  所以firefox和IE11浏览器结果为:DOM0级 DOM2级
  IE9、10浏览器结果为:DOM0级 DOM2级 IE
  IE8-浏览器结果为:DOM0级 IE
免责声明:本站部分内容、图片、文字、视频等来自于互联网,仅供大家学习与交流。相关内容如涉嫌侵犯您的知识产权或其他合法权益,请向本站发送有效通知,我们会及时处理。反馈邮箱&&&&。
学生服务号
在线咨询,奖学金返现,名师点评,等你来互动DOM0级事件,DOM2级事件,绑定事件的取消_只属于自己的感觉吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0可签7级以上的吧50个
本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:0贴子:
DOM0级事件,DOM2级事件,绑定事件的取消
DOM0级事件obj.onclick = function(){};取消obj.onclick =DOM2级事件addEventListener(event,fn,onOff);取消事件removeEventListener(event,fn,onOff);IE事件attachEvent(event,fn);取消detachEvent(event,fn);
买东西,怕质量不好?贵?买品牌商品满299减100返200(除跨境商品外)
贴吧热议榜
使用签名档&&
保存至快速回贴DOM2级事件 addEventListener() 和IE
attachEvent()的区别 - 博客频道 - CSDN.NET
vuturn的专栏
分类:javascript
DOM2级事件定义了两个方法 :addEventListener()和removeEventListener()。接受三个参数:要处理的事件名,作为事件处理的函数和一个布尔值。最后的布尔值如果是true,表示在捕获阶段调用事件处理程序,如果false,表示在冒泡阶段调用事件处理程序。
例如 :要在click事件添加处理程序,可以使用下列代码:
var btn=document.getElementById(&myBtn&);
btn.addEventListener(&click&,function(){
alert(this.id);
通过addEventListener()增加的事件处理程序只能使用removeEventListener()来移除,移除时传入的参数与添加时使用的参数相同。这意味着使用addEventListener()添加的匿名函数无法移除。
var btn=document.getElementById(&myBtn&);
btn.addEventListener(&click&,function(){
alert(this.id);
btn.removeEventListener(&click&,function(){
alert(this.id);
IE 实现了类似的两个方法:attachEvent()和detachEvent(),与DOM2级事件有很多不同。
1.传入的参数不同
attachEvent()和detachEvent()只有两个入参,一个事件名,一个是事件处理函数。attachEvent()的第一个参数,例如&onclick&,而DOM2级中addEventListener()的第一参数为&click&
2.处理的阶段不一样
IE8 及更早版本IE只支持事件冒泡 ,attachEvent()和detachEvent()添加的事件处理程序都会添加到冒泡阶段,而DOM2级可以控制,既可以捕获阶段处理也可以冒泡阶段处理。
3.事件处理程序的作用域不同
DOM2级事件添加的事件处理程序,它的作用域是所属的元素,而IE的事件处理程序会在全局作用域中运行。
var btn=document.getElementById(&myBtn&);
btn.addEventListener(&click&,function(){
console.log(this.id);
var btn=document.getElementById(&myBtn&);
btn.attachEvent(&onclick&,function(){
alert(this===window);
4.添加多个事件处理程序执行的顺序不同
DOM2级为单个元素添加多个事件处理程序后,其执行顺序按照它们添加的顺序执行,IE则是以相反的顺序执行
var btn=document.getElementById(&myBtn&);
btn.addEventListener(&click&,function(){
btn.addEventListener(&click&,function(){
执行顺序 1 ,2
var btn=document.getElementById(&myBtn&);
btn.attachEvent(&onclick&,function(){
btn.attachEvent(&onclick&,function(){
执行顺序 2, 1 ;
5.事件对象不同
兼容DOM的浏览器会将一个event对象传入事件处理程序,无论使用的是DOM0 级还是DOM2级事件。
& var btn=document.getElementById(&myBtn&);
btn.onclick=function(event){
alert(event.type);
var btn=document.getElementById(&myBtn&);
btn.addEventListener(&click&,function(event){
alert(event.type);
与访问DOM中的event对象不同,要访问IE中的event对象有几种不同的方式,取决于事件处理的类型。在使用DOM0级事件时,event对象作为全局对象window的一个属性。存在。
IE DOM0级:
var btn=document.getElementById(&myBtn&);
btn.onclick=function(){
var event=window.
alert(event.type);
IE attachEvent():
var btn=document.getElementById(&myBtn&);
btn.attachEvent(&onclick&,function(event){
alert(event.type);
DOM2级中的event对象与IE中event对象的属性和方法不同:
&(1)DOM2级stopPropagation()与IE cancelBubble
& &DOM2级的stopPropagation()方法可以取消事件冒泡,IE对应的为cancelBubble属性,当cancelBubble设置为true时就可以取消事件冒泡。
& &(2)DOM2级preventDefault()与IE &returnValue
DOM2级preventDefault()方法可以取消事件的默认行为(前提是cancleable为true),IE与之对应的是returnValue,当returnValue的值为true时,就可以取消事件的默认行为。
& &(3)DOM2级target 与IE srcElement
& DOM2级的target取得事件的目标,IE 与之对应的是srcElement。
排名:千里之外
(25)(2)(11)(11)(8)(12)(2)(18)(10)(0)(1)(5)(2)(4)(0)(1)(2)(1)下次自动登录
现在的位置:
& 综合 & 正文
译:DOM2中的高级事件处理
17.2. DOM2中的高级事件处理(Advanced Event Handling with DOM Level 2)
迄今为止,在本章中出现的事件处理技术都是DOM0级的一部分,所有支持JavaScript的浏览器都支持DOM0的API.DOM2定义了高级的事件处理API,和DOM0的API相比,有着令人瞩目的不同(而且功能更强大).虽然DOM2标准并没有把已有的API收入其中,但是DOM0级API也没有被去除.对于基本的事件处理任务,你会觉得使用这些简单的API更自由一些.
DOM2事件模型被除了IE以外的所有浏览器支持.17.2.1. 事件传播(Event Propagation)
在DOM0级事件模型中,浏览器分派事件给发生事件的文档元素.如果那个对象有相应的事件处理,那么就运行该程序.再没有更多的事情发生了.情况在DOM2中就是复杂得多.在DOM2高级事件模型中,当一个文档元素(被叫做事件的目标(target)对象)触发了一个事件,这个目标对象的事件处理程序被触发,除此之外,该目标对象的每一个祖辈元素都有一个或者两个机会去处理该事件.事件传播的过程包括三个阶段.
首先,在捕获阶段(capturing phase),事件是从文档对象(Document object)开始,沿着文档树向下一直到目标对象传播的.如果任何目标对象的祖辈(不包括目标对象本身)也有一些指定注册的捕获事件的处理程序,在事件传播的这个阶段(捕获阶段)将运行它们.(一会儿你就会看到如何注册正常事件处理程序和捕获事件处理程序.)
事件传播的下一个阶段发生在目标对象自身:所有注册到目标对象的对应事件处理程序都被运行.这和DOM0提供的事件模型是相似的.
事件传播的第三阶段是冒泡阶段,或者说按文档层次倒序的,从目标元素到文档对象(Document object).尽管所有的事件都受事件传播的捕获阶段(capturing phase)的影响,但是,并不是所有类型的事件都冒泡:例如,除了被定义了提交事件(submit)的form以外,把这个事件向上传播到文档元素是没有任何意义的.另一方面,像mousedown这样的一般事件对文档中的其它元素是有意义的,所以这些事件才沿着文档层次向上冒泡,并且触发目标元素的祖辈元素的相应事件的处理程序.通常情况下,原始的输入事件冒泡,而高级的语义事件不会.(稍候在本章中出现的表17-3是一个权威的列表,它指出哪些事件是冒泡的,哪些不是.)
在事件传播期间,每个事件的处理程序都可以阻止事件的进一步传播,只需通过调用表现这个事件的事件对象的stopPropagation( )方法就可以.事件对象和stopPropagation( )方法一会儿再进一步讨论.
一些事件会使浏览器执行一个与事件相关联的默认行为.例如,当点击一个链接(&a& tag)的时候,浏览器的默认行为是转向超链接.像这样的默认行为,只有事件传播的三个阶段都完成了才会执行,在事件传播过程中调用的任何处理程序都能阻止默认行为的发生,调用事件对象的preventDefault( )方法就可以了.
尽管这种事件传播机制似乎让人难以理解,但是它有助于你集中你的事件处理.DOM1指出了所有的文档元素,还指出了在那些元素上允许发生的事件(如mouseover事件).这就意味着,与旧的DOM0事件模型相比,DOM1是在很多很多的地方注册事件处理程序.假设你想在鼠标经过每一个文档中的段落元素(&P&)时触发一个事件处理程序.除了在所有的段落标签(&p&tag)注册一个onmouseover事件处理程序之外,取而代之的办法是为文档对象(Document object)注册一个单独的事件处理程序,然后,或者在捕获阶段,或者在冒泡阶段,处理这些事件.
事件传播还有一个很重要的细节.在DOM0模型中,你只能为一个特定的对象的一个特定类型的事件注册一个处理程序.而在DOM2模型中,你可以为一个特定对象的一个特定类型事件注册任意数量的事件处理程序.这也适用于事件传播时,在捕获阶段或者冒泡阶段,事件对象的祖辈的处理函数被调用的情况.
17.2.2. 事件处理程序的注册(Event Handler Registration)
在DOM0的API中,你通过在HTML中设置属性(attribute)或者在JavaScript中设置一个对象的属性(property)的方法注册事件.而在DOM2模型中,你通过调用那个对象的addEventListener( )方法注册事件处理程序.(DOM标准在这个API里使用了术语listener,但是在本文中,我将继续使用这个术语的同义词:handler.)这个方法有三个参数.第一个是被注册的事件类型.事件类型是一个字符串,包含小写的,去掉开头的"on"的HTML中的事件属性名.如果你在DOM0里使用HTML属性onmousedown,你在DOM2中就是使用字符串"mousedown".
第二个参数是指定类型的事件触发的时候应该调用的监听函数.在你的函数被调用的时候,传入了唯一的一个参数:Event对象.这个对象包含了事件的细节信息(如:哪个鼠标键被按下)和一些方法,如:stopPropagation( ).在本章后面将深入讨论事件接口和它的子接口.
addEventListener( )函数的最后一个参数是一个布尔值.如果为true,指定的事件处理程序在事件传播的捕获阶段将捕获事件.如果是false,事件处理程序就是一个正常的事件处理程序了,只有在事件直接发生在该对象上或者发生在子代对象上向上冒泡到达这个元素时,处理程序才被调用.
举个例子,你可以像下面这样使用addEventListener( )方法给一个form元素注册一个提交事件(submit):
document.myform.addEventListener("submit",
function(e) {return validate(e.target); }
如果你想捕获发生在一个特定名字的div中的鼠标按下(mousedown)事件,你可以这样使用addEventListener( ):
var mydiv = document.getElementById("mydiv");mydiv.addEventListener("mousedown", handleMouseDown, true);
注意,这些例子假设你已经在你的JavaScript代码中定义了函数名为validate( )和handleMouseDown( )的函数.
用addEventListener( )函数注册的事件监听程序运行在它们被定义的作用域.它们并不是在参数的作用域链中被调用的.
因为在DOM2中通过调用一个方法来给对象添加事件监听器,而不是通过设置HTML属性或者JavaScript属性的方法,所以,你可以给一个指定对象的一个特定事件注册多于一个的事件监听程序.如果你通过调用addEventListener( )函数为同一对象的同一事件注册多个监听程序,当那个对象上那个类型的事件发生的时候(或者是向上冒泡,或者是捕获的),所有的处理程序都被调用.重点理解一下:DOM标准并没有保证一个对象的所有监听函数被调用的顺序,因此,你不应该依赖于函数按照被注册的顺序被执行(事实上是根本不按顺序执行).还要注意的是,如果你多次注册相同的监听程序给同一个元素,只有第一次注册的有效,其余的被忽略.
为什么你想要在同一个对象的同一个事件上注册多个事件监听程序呢?因为这有助于将你的软件模块化.假设,你写了一个可重用的JavaScript代码模块,它使用图像上的mouseover事件执行图片轮换.现在再假设你有另一个模块也想使用mouseover事件来显示一些在HTML弹出窗体或者工具提示(Tool tip)上的附加信息.在DOM0的API中,你不得不把这两段代码合并成一个,这样才能共用一个图片对象的onmouseover属性.另一方面,在DOM2的API中,每一个模块都可以注册它需要的事件监听程序,而不必管其它的模块.
removeEventListener( )和addEventListener( )是一对方法,它需要与addEventListener( )同样的三个参数,但它的功能是从一个对象删除一个事件监听函数,而不是添加.它常用于临时注册一个事件监听函数,然后很快就删除这个函数.例如,你得到一个mousedown事件的时候,想为mousemove和mouseup事件注册临时的捕获事件监听函数,这样就可以知道,是否用户拖拽了鼠标.然后在mouseup事件发生的时候,解除这个注册的监听程序.在这种情况下,事件监听器的删除代码如下:
document.removeEventListener("mousemove", handleMouseMove, true);document.removeEventListener("mouseup", handleMouseUp, true);
addEventListener( )方法和removeEventListener( )方法都被定义在事件目标接口中(the EventTarget interface),在支持DOM2事件模型的Web浏览器中,元素和文档节点实现了这个接口,并且提供了这些事件注册方法.
[*] 从技术上来讲,DOM指出在文档(document)中的所有节点(包括文本节点:Text nodes)都实现了这个事件对象接口.然后事实上,web浏览器仅在元素(Element)和文档节点(Document nodes)上支持事件监听器的注册,还有窗口(Window)对象,尽管这已经超出了DOM的范围.
17.2.3. addEventListener( )和this关键字(addEventListener( ) and the this Keyword)
在原来的DOM0级事件模型中,当一个函数被注册给一个文档元素的某个事件监听程序时,它变成了那个文档元素的一个方法.当这个事件监听程序被调用时,它作为这个元素的一个方法被调用,在函数的内部,this关键字引用当前发生事件的元素.
DOM2是用一种与语言无关的方法写的,它指出监听器(listeners)是对象,而不是简单的函数.绑定了DOM的JavaScript用Javascript函数事件监听器取代对JavaScript对象使用的需求.( The JavaScript binding of the DOM makes JavaScript functions event handlers instead of requiring the use of a JavaScript object.)不幸的是,这个绑定关系并没有实际的指出监听函数如何被调用,也没有指出this关键字的值.
且不去考虑标准的不足,所有已知的实现都调用用addEventListener( )方法注册的处理程序,就像这些处理程序是目标对象的方法一样.也就是说,当监听程序被调用的时候,this关键字引用这个监听程序被注册的那个对象.如果你宁愿不依赖这种未指定的行为,你可以使用传入监听程序的事件对象(Event object)的currentTarget属性.在本章稍候的讨论中你会看到,currentTarget属性引用事件监听程序被注册的对象.
17.2.4. 把对象(Objects)注册为事件监听器(Registering Objects as Event Handlers)
addEventListener( )允许你注册一个事件监听函数.对于面向对象编程,你可能更喜欢定义一个客户端对象的方法作为事件监听程序,然后把它们作为那个对象的方法进行调用.对于Java程序员,DOM标准允许这样做:事件监听程序可以是实现了EvnentListener接口并且有一个名为handleEvent()的方法的对象.在Java中,当你注册一个事件监听程序时,你给addEventListener( )传入一个对象,而不是一个函数.简单的说,绑定了DOM API的JavaScript不需要你去实现EventListener接口,相反的,允许你直接给addEventListener( )传递一个函数引用.
然而,如果你在写一个面向对象的JavaScript程序,并且更喜欢用对象作为事件监听程序,你可以用一个像下边这样的函数来注册:
function registerObjectEventHandler(element, eventtype, listener, captures) {
element.addEventListener(eventtype,
function(event) { listener.handleEvent(event); }
captures);}
只要一个对象定义了handleEvent( )方法,就可以用这个函数把该对象注册为一个事件监听程序.那个方法作为监听对象的方法被调用,this关键字引用这个监听对象,而不是产生事件的文档元素.
尽管这不是DOM标准的一部分,Firefox(和其它基于Mozilla codebase的浏览器)允许把定义了handleEvent()方法的事件监听对象直接传递给addEventListener()方法,来代替函数.对于这些浏览器,就没有必要定义一个像刚才展示的注册函数了.
17.2.5. 事件模型和事件类型(Event Modules and Event Types)
如我前面所说,DOM2是模块化的,所以,一个实现可以支持其中的一部分而忽略其它对其它部分的支持.事件API(Events API)就是这样一个模块.你可以像这样来测试一个浏览器是否支持这个模块:
document.implementation.hasFeature("Events", "2.0")
然而,事件模块只包含用于基本事件监听结构的API.子模块提供对特定类型事件的支持.每个子模块都提供对一类相关事件类型的支持,并且定义了传入事件监听程序的事件类型.例如,名为MouseEvents的子模块提供了mousedown, mouseup, click等相关事件的类型.它也定义了MouseEvent接口.实现了那个接口的对象,为任何一个被这个模块支持的事件类型,被传入事件监听程序.
表17-2列出了每一个事件模块,它定义的接口,和被它支持的事件类型.注意,DOM2并没有把任何键盘事件标准化,因此这里没有列出键盘事件模块.然而,当前的浏览器都支持键盘事件,在本章的后面,你会了解的更多一些.(此处省略几句和MutationEvents模块相关的描述)
Table 17-2. Event modules, interfaces, and types
HTMLEvents
abort, blur, change, error, focus, load, reset, resize, scroll, select, submit, unload
MouseEvents
MouseEvent
click, mousedown, mousemove, mouseout, mouseover, mouseup
DOMActivate, DOMFocusIn, DOMFocusOut
如你在表17-2中所见,HTMLEvents和MouseEvents模块定义的事件类型和DOM0的事件模块是非常相似的.UIEvents模块定义了事件类型,这和被HTML表单元素支持的focus,blur和click事件很相似,但更通用的,所以,他们能被任何可以接受焦点或者被激活的文档元素产生.
如前所述,当一个事件发生的时候,它的监听程序被传入一个实现了那个类型事件的事件接口对象.这个对象的属性提供了对事件监听程序可能有用的细节信息.表17-3再一次列出标准的事件,但这次是按事件类型组织的,而不是事件模型.对于每个事件类型,该表都指出传入它的监听程序的事件对象的种类,是否这个事件有一个可以用preventDefault()方法阻止发生的默认行为.对于HTMLEvents模块中的事件,表格中的第五列指出哪些HTML元素可以产生该事件.对于所有其它的事件类型,第五列指出事件对象的哪些属性包含了有意义的事件细节信息.注意,在这一列中列出的属性,不包括被基本事件接口定义的对所有事件类型都有意义的属性.
Table 17-3. Event types
&img&, &object&
&a&, &area&, &button&, &input&, &label&, &select&, &textarea&
&input&, &select&, &textarea&
MouseEvent
screenX, screenY, clientX, clientY, altKey, ctrlKey, shiftKey, metaKey, button, detail
&body&, &frameset&, &img&, &object&
&a&, &area&, &button&, &input&, &label&, &select&, &textarea&
&body&, &frameset&, &iframe&, &img&, &object&
MouseEvent
screenX, screenY, clientX, clientY, altKey, ctrlKey, shiftKey, metaKey, button, detail
MouseEvent
screenX, screenY, clientX, clientY, altKey, ctrlKey, shiftKey, metaKey
MouseEvent
screenX, screenY, clientX, clientY, altKey, ctrlKey, shiftKey, metaKey, relatedTarget
MouseEvent
screenX, screenY, clientX, clientY, altKey, ctrlKey, shiftKey, metaKey, relatedTarget
MouseEvent
screenX, screenY, clientX, clientY, altKey, ctrlKey, shiftKey, metaKey, button, detail
&body&, &frameset&, &iframe&
&input&, &textarea&
&body&, &frameset&
DOMActivate
DOMFocusIn
DOMFocusOut
被DOM0和DOM2支持的事件类型大体相同(UIEvents除外).DOM2标准添加了对abort,error,resize和scroll事件类型的支持,这些不是HTML 4的标准,但它不支持HTML 4标准中的键盘事件和双击事件.(取而代之的是,传入click事件处理程序的对象的细节属性指出了发生的连续点击的次数.)
17.2.6. 事件接口和事件细节(Event Interfaces and Event Details)
一个事件发生的时候,DOM2提供了关于这个事件的其它细节(例如何时何地发生的),这些信息作为传入到事件监听程序的对象的属性出现.每一个事件模块都有一个相关联的事件接口,该接口指出和那个类型事件相关的细节.表17-2列出了三种不同的事件模块和三种不同的事件接口.
事实上这三个接口是互相关联的,并且形成了一个层次关系.事件接口是这个层次的根层;所有的事件对象都实现了它大部分基本的事件接口.UIEvent是事件接口的子接口:任何实现了UIEvent接口的事件对象都实现了Event接口的属性和方法.MouseEvent接口又是UIEvent的子接口.举个例子,这就是说,传给点击事件处理程序的事件对象实现了在MouseEvent, UIEvent, 和Event接口中定义的所有属性和方法.
接下来的部分介绍的是事件接口,并且着重讲最重要的属性和方法.
17.2.6.1. 事件(Event)
在HTMLEvents模块中定义的事件类型使用Event接口.所有其它的事件类型都使用Event的子接口,子接口被所有的事件对象实现,并且提供了应用于那个事件类型的细节信息.事件接口定义了如下属性(注意,这些属性和所有事件子接口的属性都是只读的):
发生的事件类型.这个属性的值是事件类型的名字,它和用于注册事件处理程序时使用的字符串是一样的(如: click 或者 mouseover).
事件发生的节点,可能与currentTarget不同.
currentTarget
正在处理事件的节点(也就是正在运行的事件处理程序所属的节点).如果在事件被捕获或者冒泡阶段被处理,这个属性的值和target属性的值是不同的.如前所述,你可以在你的事件处理程序中用这个属性代替this关键字
eventPhase
指出正在理的是事件传播的哪一个阶段的数值.该值为三个常中之一:Event.CAPTURING_PHASE, Event.AT_TARGET, 或者 Event.BUBBLING_PHASE.
指出该事件何时发生的日期对象
指出该事件是否沿文档树向中冒泡的布尔值.
cancelable
指出该事件是否有一个可以用prevertDefault()阻止的和事件相关联的默认行为的布尔值.
除了这七个属性以外,事件接口定义了两个方法,也都被事件对象实现了,它们是:stopPropagation( ) 和 preventDefault( ).任何事件处理程序都可以调用stopPropagation( )来阻止正在被传播的事件越过正在被处理的节点.任何事件处理程序都可以调用preventDefault( )来阻止浏览器执行与该事件关联的默认行为.在DOM2中调用preventDefault( ),就像在DOM0中返回false.
17.2.6.2. 用户信息事件(UIEvent)
用户信息事件接口是Event的子接口.它定义了被传递到DOMFocusIn, DOMFocusOut和DOMActivate的事件对象的类型.这些事件类型通常是用不到的;但对于UIEvent接口来讲,比较重要的是它是MouseEvent的父接口.除了在Event中定义的属性外,UIEvent还定义了两个属性:
发生的事件所在的窗口对象(Window Object:known as a view in DOM terminology).
可以提供附加信息的数值.对于click,mousedown和mouseup事件,这个字段代表点击计数:1代表单击,2代表双击,3代表三击.(注意,每次点击都产生一个事件,但是如果多次点击间隔足够短,detail属性就会指示出来.也就是说,detail为2的鼠标事件要优先于detail为1的鼠标事件.)对于DOMActivate事件,这个字段值为1代表正常激活,2代表极度活跃(hyperactivation),比如双击或者Shift-Enter组合键.
17.2.6.3. MouseEvent
MouseEvent接口继承了Event和UIEvent的属性和方法,还定义了如下附加属性:附加属性:
数值类型,指出在mousedown, mouseup或者click事件期间哪一个鼠标键改变了状态.0代表左键,1代表中键,2代表右键.只有当一个按键改变状态时,才使用这个属性;例如:不能用于报告mousemove事件发生时哪个键是被按下的.注意Netscape 6得到的值为1,2,3,而不是0,1,2.这个问题在Netscape 6.1中已经修正了.
altKey , ctrlKey, metaKey, shiftKey
这四个布尔值代表,当一个鼠标事件发生时,是否 Alt, Ctrl, Meta或者Shift键被按下.与button属性不同,这些按键属性对于任何鼠标事件都是有效的.
clientX, clientY
这两个属性指出鼠标指针的X和Y坐标,相对于浏览器窗口的客户区.注意这个坐标并没有计算文档的滚动高度或者宽度在内:如果事件发生在窗口的最上边,不管这个文档已经向下滚动了多远,clientY就是0.不幸的是,DOM2并没有提供一个标准的方法去转换这个窗口坐标为文档坐标.在除了IE以外的浏览器中,你可以加上window.pageXOffset和window.pageYOffset.
screenX, screenY
这两个属性指出鼠标指针相对于用户显示器的左上角的坐标.如果你打算在鼠标事件发生的地点或者附近打开一个窗口,这两个属性就有用了.
relatedTarget
这个属性引用一个相对于事件的target节点的节点.对于mouseover事件,它引用当鼠标经过target节点时鼠标离开的那个节点.对于mouseout事件,它引用当鼠标离开目标节点时,鼠标进入的节点.对于其它事件,这两个属性是无用的.
17.2.7. 混合事件模型(Mixing Event Models)
到现在为止,我们讨论了传统的DOM0级事件模型,和新的标准的DOM2模型.为了向后兼容,支持DOM2模型的浏览器将继续支持DOM0级事件模型.这就意味着,你可以在一个文档里混合使用这两种事件模型.
支持DOM2级事件模型的web浏览器总是传递一个事件对象给事件监听程序,这和用DOM0级事件模型的HTML属性或者JavaScript属性注册事件处理程序是一致的,理解这一点很重要.当事件监听程序作为一个HTML属性被定义的时候,它被暗中转换成一个函数,这个函数有一个名为event的参数.这就意味着,像这样的一个事件监听程序可以用标识符event来引用事件对象.
DOM标准承认DOM0级事件模型继续保留使用,并指出,对待DOM0事件模型的监听程序的注册方法就像用addEventListener( )注册的一样.也就是说,如果你给一个文档元素e的onclick属性赋值为函数f(或者说设置对应的HTML中的onclick属性),它和下面这种注册方法是一样的:
e.addEventListener("click", f, false);
当函数f被调用的时候,传入一个事件对象作为参数,尽管这个函数是用DOM0模型注册的.
&&&&推荐文章:
【上篇】【下篇】}

我要回帖

更多关于 dom0级和dom2级的区别 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信