javascript 事件整理
由于之前学习javascript时,只是看书并不做笔记,在编码时也不什么主意一些问题的总结,以致javascript的学习进度停滞不前,最近重新看了一次书,感觉很多知识因为不常用竟陌生了许多。因此重新学习和粗略整理一下。ps:参考资料《javascript高级程序设计第三版》
一、事件流
事件流主要描述的是从页面中接受事件的顺序。但是IE和Netscape却有两种不同的事件流。
1、事件冒泡
IE的事件流,概念:即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档节点);兼容性:所有的现代浏览器都支持事件冒泡,但具体实现上还是有一点差别。IE9、Firefox、Chrome和Safari 则将事件一直冒泡到window对象,IE5.5及更早版本中的事件冒泡会跳过<html>元素(从<body>直接跳到document。)
2、事件捕获
Nestcape的事件流,概念:不太具体的节点应该更早接受到事件,而最具体的节点应该最后接受到事件,目的是在事件到达预定目标之前捕获它;兼容性:Netscape Communicator 唯一支持的事件流模型,但IE9、Safari、Chrome、Opera和Firefox目前也支持这种事件流。但少人用
3、DOM事件流
“DOM2级事件”规定的事件流包括三个阶段:(1)事件捕获阶段,(2)处于目标阶段,(3)事件冒泡阶段;概念:首先发生的是事件捕获,为截获事件提供了机会,然后是实际的目标接受到事件,最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。总的来说综合了前两种事件流。兼容性:IE9、Opera、Firefox、Chrome、Safari都支持DOM事件流;IE8及更早版本不支持DOM事件流。
总结:事件冒泡兼容性好,放心使用。
二、事件处理程序
1、HTML事件处理程序。
特点:某个元素支持的每种事件,都可以使用一个与相应事件处理程序同名的HTML特性来指定。这个特性的值应该是能够执行的javascript代码,事件处理程序中的代码在执行时,有权访问全局作用域中的任何代码,也可以访问外部文件中的函数代码。例子:
<input type="button" value="Click Me" onclick="alert('clicked')"/>
注意:特性中的javascript代码可以通过this 访问当前元素的任何属性,同时可以直接通过event访问事件,例如:
<input type="button" value="Click Me" onclick="function(){alert(this.id + ' '+ event.type);}">
缺点:(1)用户在DOM节点结构未加载完时触发事件,事件尚未具备执行条件,会抛出错误(2)html和javascript耦合太紧,不利于管理和维护,建议避免使用。
2、DOM0级事件处理程序
特点:通过javascript指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性(全部小写,例如onclick),前提条件是必须取得一个要操作的对象的引用。优势:(1)简单,(2)具有跨浏览器的优势。以这种方式添加的事件处理程序会在事件流冒泡阶段被处理。
var btn = document.getElementById("myBtn"); btn.onclick = function (){ alert(this.id); }
注意:DOM0级事件处理程序中通过this可以访问元素的任何属性和方法。
缺点:一个属性只能指定赋值一个事件处理程序,若赋值多个,则被覆盖,以最后的赋值为标准。也可以赋值为null(则删除以这种方式指定的事件处理程序)。
3、DOM2级事件处理程序
定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener(),并且它们都接受3个参数(1)要处理的事件名,(2)作为事件处理程序的函数(3)一个布尔值(true表示在捕获阶段调用,false表示在冒泡阶段调用)。所有DOM节点都有这两个方法。
优点:可以添加多个事件处理程序。
var btn = document.getElement("myBtn"); btn.addEventListener("click",function(){ alert( this.id );},false); btn.addEventListener("clcik",function(event){ alert(event.type);},false);
注意:这两个事件处理函数会按照添加它们的顺序触发。同时如果在addEventListener()中使用到匿名函数作为事件处理程序时,则无法用removeEventListener()移除该事件处理程序,大多情况下,都是将事件处理程序添加到事件流的冒泡阶段,也即布尔值为false;
兼容性:IE9、Firefox、Safari、Chrome和Opera支持DOM2级事件处理程序。
4、IE事件处理程序
IE中也定义了两个方法:attachEvent()和detachEvent(),这两个方法接受相同的两个参数(1)“on”+事件处理程序名称(2)事件处理程序函数 ;这两个方法添加的事件处理程序都会被添加到冒泡阶段。
优点:可以添加多个事件处理程序。
var btn = document.getElementById("myBtn"); btn.attachEvent("onclick",function(){ alert(this === window);});
注意:用attachEvent()添加的匿名函数将不能被移除,只要能够将对相同函数的引用传给detachEvent(),就可以移除相应的事件处理程序。
兼容性:支持IE事件处理程序的浏览器有IE和Opera。
三、事件对象
1、DOM中的事件对象
兼容DOM的浏览器会将一个event对象传入到事件处理程序中。无论指定事件处理程序时使用什么方法(DOM0级或DOM2级),都会传入event对象。
var btn = document.getElementById("myBtn"); btn.onclick = function(event){ alert(event.type); }; btn.addEventListener("click",function(event){ alert(event.type); },false)
<input id=“btn” type="button" value="Click Me" onclick="alert(event.type)"/>/*三种样例的效果一样*/
DOM中的event对象的属性和方法如下:
属性/方法 类型 说明
bubbles 布尔值 表明事件是否冒泡
cancelable 布尔值 表明是否可以取消事件的默认行为
currentTarget Element 其事件处理程序当前正在处理事件的那个元素
target Element 事件的目标
trusted 布尔值 为true表示是浏览器生成的,false是开发人员通过javascript创建的(DOM3级事件中新增)
type String 被触发的事件的类型
view AbstractView 与事件关联的抽象视图。等同于发生事件的window对象
defaultPrevented 布尔值 为true则表示已经调用了preventDefault(); {DOM3级事件中新增}
detail Integer 与事件相关的细节信息
eventPhase Integer 调用事件处理程序的阶段:1表示捕获阶段,2表示“处于目标”,3表示冒泡阶段
preventDefault() Function 取消事件的默认行为,如果cancelable的值为true,则可以使用这个方法
stopPropagation() Function 取消事件的进一步捕获或冒泡。如果bubbles为true,则可以使用这个方法
stopImmediatePropagation() Function 取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用(DOM3中新增)
【注意:以上属性或方法都是只读。】
事件处理程序中的this、currentTarget与target的区别:
在事件处理程序中对象this始终等于currentTarget的值(也就事件处理程序所被指定的元素对象中),而target则只包括事件的实际目标(就是真实触发的元素,目标元素)。
2、IE中的事件对象
与访问DOM中的event对象不同,要访问IE中的event对象有几种不同的方式,取决于指定事件处理程序的方法。在使用DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在。
var btn = document.getElementById("myBtn"); btn.onclick = function(){ var event = window.event; alert( event.type ); }
注意:如果事件处理程序是使用attachEvent()添加的,那么就会有一个event对象作为参数被传入事件处理程序函数中。
var btn = document。getElementById("myBtn"); btn.attachEvent("onclick",function(event){alert(event.type);});
IE中的事件对象event的属性或方法:
属性或方法 类型 说明
type String 被触发的事件类型
srcElement Element 事件目标(与dom中的target属性同功能)
cancelBuble 布尔值 默认值是false,但将其设置为true就可以取消事件冒泡,(与dom中的stopPropagation()相同)
returnValue 布尔值 默认值为true,但将其设置为false就可以取消事件的默认行为(与dom中的preventDefault()相同)
【 type,srcElement属性为只读,其他两个为读/写】
四、跨浏览器的事件处理程序(综合)
var EventUtil = { addHandler: function(element,type,handler){ if( element.addEventListener ) element.addEventListener(type,handler,false); else if( element.attachEvent ) element.attachEvent("on"+type,handler); else element["on"+type] = handler; }, removeHandler: function(element,type,handler){ if( element.removeEventListener ) element.removeEventListener(type,handler,false); else if( event.detachEvent) element.detachEvent("on"+type,handler); else element["on"+type] =null; }, getEvent: function( event ){ return event ? event : window.event; }, getTarget: function( event ){ return event.target || event.srcElement; }, preventDefault: function( event ){ if( event.preventDefault ) event.preventDefault(); else event.returnValue = false; }, stopPropagation: function( event ){ if( event.stopPropagation ) event.stopPropagation(); else event.cancelBubble = true; } }