事件流是描述从页面中接收数据的顺序,但是IE和Netspace开发团队提出了差不多完全相反的事件流概念。IE事件流是事件冒泡,而Netspace Comminicator 的事件流是事件捕获。
一、DOM事件流
“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段,在DOM事件流中目标元素在捕获阶段不会接受到数据,而是作为事件冒泡阶段的一部分。
二、事件处理程序
事件处理程序就是相应某个事件的函数,为事件指定处理程序的方式有以下几种:
1、HTML事件处理程序
在元素标签内绑定:
<script>
function showMessage(){
console.log('hello world')
}
</script>
<input type = "button" onclick = "showMessage()" />
2、DOM0级事件处理程序
这是通过JavaScript指定事件处理的传统方式,讲一个函数赋值给一个事件处理程序属性。这种方式是在第四代Web浏览器中出现的,至今依然被所有浏览器支持。原因一是简单,二是具有跨浏览器优势;
var btn = document.getElementById("myButton");
btn.onclick = function(){
console.log('hello world')
}
3、DOM2级事件处理程序
DOM2级事件处理定义了两个方法:addEventListener() 和 removeEventListener()用于处理事件程序和删除事件处理程序操作,相信大家对这两个方法已经不陌生了,在此不做详细介绍。
在DOM事件处理中,this指向当前元素!!!!!
目前支持DOM2级事件处理程序的浏览器:IE9、Firefox、Chrome、Opera
4、IE事件处理程序
IE实现了与DOM中类似的两个方法:attachEvent() 和 detachEvent(),由于IE8以前的版本只支持事件冒泡,所以通过上述添加的事件都会被添加到冒泡阶段。
IE事件处理中,this指向window!!!!!在编写跨浏览器代码时一定注意!!!!
三、事件对象
1、DOM中的事件对象
在触发DOM上的某个事件时,会产生一个事件对象event,包含着与事件有关的信息。
兼容DOM的浏览器会将一个event对象传入到事件处理程序中,无论是DOM0级还是DOM2级。
只有在事件处理程序执行期间,event对象才存在,一旦事件处理程序完成,event就会被销毁。
在事件处理程序内部,对象this始终等于currentTarget的值,而target则只是包含事件的实际目标。
event 包含的属性和方法:
| 属性/方法 | 类型 | 读/写 | 说明 |
|---|---|---|---|
| bubbles | Boolean | 只读 | 表明事件是否冒泡 |
| stopPropagation() | Function | 只读 | 取消事件的进一步捕获或冒泡。如果bubbles为true,则可以使用这个方法 |
| stopImmediatePropagation() | Function | 只读 | 取消事件的进一步捕获或冒泡 ,同时阻止任何事件处理程序被调用(DOM3级事件中新增) |
| cancelable | Boolean | 只读 | 表明是否可以取消事件的默认行为 |
| preventDefault() | Function | 只读 | 取消事件的默认行为。如果cancelable是true,则可以使用这个方法 |
| defaultPrevented | Boolean | 只读 | 为true表示已经调用了preventDefault()(DOM3级事件中新增) |
| currentTarget | Element | 只读 | 其事件处理程序当前正在处理事件的那个元素(currentTarget始终===this,即处理事件的元素) |
| target | Element | 只读 | 直接事件目标,真正触发事件的目标 |
| detail | Integer | 只读 | 与事件相关的细节信息 |
| eventPhase | Integer | 只读 | 调用事件处理程序的阶段:1表示捕获阶段,2表示处于目标阶段,3表示冒泡阶段 |
| trusted | Boolean | 只读 | 为true表示事件是由浏览器生成的。为false表示事件是由开发人员通过JavaScript创建的(DOM3级事件中新增) |
| type | String | 只读 | 被触发的事件的类型 |
| view | AbstractView | 只读 | 与事件关联的抽象视图。等同于发生事件的window对象 |
2、IE中事件对象
与DOM中的事件对象不同,要访问IE中的event对象有几种不同的方式,取决于事件处理程序的方法:
- 用DOM0级方法添加事件处理程序时,event对象是作为window的一个属性存在,所以必须通过window.event获取
- 如果是通过attacheEvent()添加的,那么event会作为参数传入(同DOM事件对象)
IE的event对象属性:
| 属性/方法 | 类型 | 读/写 | 说明 |
|---|---|---|---|
| cancelBubble | Boolean | 读/写 | 默认为false,但将其设置为true就可以取消事件冒泡(与DOM中stopPropagation()方法的作用相同) |
| returnValue | Boolean | 读/写 | 默认为true,但将其设置为false就可以取消事件的默认行为(与DOM中的preventDefault()方法的作用相同) |
| srcElement | Element | 只读 | 事件的目标(与DOM中的target属性相同) |
| type | String | 只读 | 被触发的事件的类型 |
四、跨浏览器事件解决方案
综上所述,编写跨浏览器的事件处理程序:
var EventUtil = {
addHandler: function(element, type, handler){
if(element.addEvenListener){
element.addEventListener(type, handler, false);
}else if(element.attachEvent){
element.attacheEvent("on" + type, handler);
}else{
element["on" + type] = handler;
}
},
removeHandler:function(){
if(element.addEvenListener){
element.removeEventListener(type, handler, false);
}else if(element.attachEvent){
element.detacheEvent("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
}
}
}