本章内容:
- 理解事件流
- 使用事件处理程序
- 不同的事件类型
一、事件流
- 事件,就是文档或浏览窗口发生的一些特定的交互瞬间
- JavaScript与HTML 之间的交互是通过事件实现的。
- 事件流,描述的是从页面上接收事件的顺序。(IE的事件流是事件冒泡流,而Netscape的事件流是事件捕获流)
-
- 事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。
- 事件捕获(event capturing),即不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。(和事件冒泡完全相反)
- DOM事件流:DOM2级事件规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段
二、事件处理程序
事件就是用户或浏览器自身执行的某种动作。诸如click、load 和 mouseover , 都是事件的名字。而响应某个事件的函数就叫做
事件处理程序(或
事件侦听器)
为事件指定处理程序的方式:
- HTML 事件处理程序
- DOM0 级事件处理程序
- DOM2 级事件处理程序(IE9、Opera、Firefox、Chrome 和 Safari都支持DOM事件流)
- IE 事件处理程序 (IE8及更早版本 和 Opera 支持IE事件处理程序)
- 跨浏览器的事件处理程序(其实就是上面的综合而已)
1、HTML 事件处理程序
<div id="box">
<input type="button" value="按钮" id="btn"
οnclick= "showMessage()">
</div>
<script>
function showMessage(){
alert("hello world!");
}
</script>
缺点:
- 存在时差问题。用户可能在HTML元素一出现就会在页面上去触发相应事件,但当时的事件处理程序可能尚不具备执行条件。
- 其次,这样扩展事件处理程序的作用域链在不同浏览器中会导致不同的结果。
- 另外(最重要的),HTML和JavaScript代码紧密耦合在一起。这就意味着,如果需要更换事件处理程序,就需要改动两处:HTML代码 和JavaScript代码。
2、DOM0 级事件处理程序
——较传统的方式:把一个函数赋值给一个事件的处理程序属性。
——用的比较多的方法:①简单 ②具有跨浏览器的优势
<div id="box">
<input type="button" value="按钮2" id="btn2" >
</div>
<script>
var btn2=document.getElementById('btn2'); //获取需要添加事件处理程序的元素
btn2.onclick=function(){ //把一个函数赋值给一个事件处理程序属性(即 onclick)
alert("这是通过DOM0 级添加的事件")
}
btn2.οnclick=null; //也可以删除通过DOM0级方法指定的事件处理程序
</script>
3、DOM2 级事件处理程序
DOM2级事件定义了两个方法,用于处理指定和删除事件处理程序的操作:
- addEventListener( )
- removeEventListener( )
所有DOM节点都包含这两个方法,它们接受
3个参数:
- 要处理的事件名(如click等)
- 作为事件处理程序的函数
- 一个布尔值 (true:表示在捕获阶段调用事件处理程序;false:(优先选择) 代表在冒泡阶段调用事件处理程序)(大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度的兼容各种浏览器。)
<div id="box">
<input type="button" value="按钮3" id="btn3" >
</div>
<script>
//作为事件处理程序的函数
function showMessage(){
alert("hello world!");
}
//DOM2级事件
var btn3=document.getElementById('btn3'); //获取需要添加事件的元素节点
btn3.addEventListener("click", showMessage,false); //添加 事件处理程序
btn3.addEventListener("click",function(){ //DOM0级和DOM2级都可以添加多个事件处理程序
alert(this.value);
}, false);
//btn3.
removeEventListener
("click",showMessage,false); //删除事件处理程序
</script>
4、IE事件处理程序(只在IE8及更早版本 和 opera 浏览器中得以支持)
IE实现了与DOM中类似的两个方法:
- attachEvent( )
- detachEvent( )
这两个方法接收相同的连个参数:(
去掉了DOM事件处理程序中的布尔值 )
- 事件处理程序名称
- 事件处理程序函数
不使用第三个参数的原因:IE8以及更早的浏览器版本只支持事件冒泡!!!
<div id="box">
<input type="button" value="按钮4" id="btn4" >
</div>
<script>
//作为事件处理程序的函数
function showMessage(){
alert("hello world!");
}
var btn4=document.getElementById('btn4'); //获取需要添加事件处理程序的元素节点
btn4.attachEvent("onclick",showMessage); //添加事件处理程序
btn4.detachEvent("onclick",showMessage); //删除事件处理程序
</script>
5、跨浏览器的事件处理程序
<div id="box">
<input type="button" value="按钮4" id="btn4" >
</div>
<script>
function showMessage(){
alert("Hello World!");
}
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(element.detachEvent) {
element.detachEvent("on" + type, handler)
} else {
element["on" + type] = null;
}
}
};
var btn4 = document.getElementById("btn4");
eventUtil.addHandler(btn4, "click", showMessage);
//eventUtil.removeHandler(btn4, "click", showMessage);
</script>
三、事件对象(
event)(这一块儿内容还是看书吧 每个例子都要好好看)
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。如:鼠标操作导致的事件对象中,会包含鼠标位置的信息,而键盘操作导致的事件对象中,会包含与按下的键有关的信息。所有的浏览器都支持event对象,但支持的方式不同。
1、DOM中的事件对象
主要有一些常用的属性:
- type属性 用于获取事件类型
- target属性 用于获取事件目标,即事件发生在哪个element
- stopPropagation( )方法 用于阻止事件冒泡
- preventDefault( )方法 用于阻止特定事件的默认行为
2、IE中的事件对象
属性:
- type属性 用于获取事件类型
- srcElement属性 用于获取事件目标(相当于DOM中的target)
- cancelBubble属性 默认值为false,但将其设置为true就可以取消事件冒泡(与DOM中的stopPropagation( )方法的作用相同)
- returnValue属性 默认值为false,但将其设置为true就可以取消事件的默认行为(与DOM中的preventDefault( )方法的作用相同)
3、跨浏览器的事件对象
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.addEventListener){
element.removeEventListener(type, handler, false)
} else if(element.attachEvent) {
element.detachEvent("on" + type, handler)
} else {
element["on" + type] = null;
}
},
//获取event对象
//在兼容DOM的浏览器中,event变量只是简单地传入和返回。而在IE中,event参数是未定义的(undefined),因此就会返回window.event。
getEvent: function(event){
return event?event : window.event ;
},
//获取被触发的事件的类型
getType: function(event){
return event.type;
},
//获取事件的目标
getTarget: function(event){
return event.target || event.srcElement;
},
//取消事件的默认行为
preventDefault: function(evert){
if(event.preventDefault){
event.preventDefault();
} else {
event.returnValue=false;
}
},
//取消事件冒泡
stopPropagation: function(event){
if(event.stopPropagation){
event.stopPropagation();
} else {
event.cancleBubble=true;
}
}
};
以上为自建的一个跨浏览器的事件处理程序的对象。下面举例介绍体现如何使用
//添加、删除事件处理程序
var btn = document.getElementById("myBtn");
var handler = function() {
alert("Hello World!");
};
eventUtil.addHandler(btn, "click", handler);
eventUtil.removeHandler(btn, "click", handler);
//获取事件对象
btn.onclick = function(event) {
event = eventUtil.getEvent(event);
};
//注意啦::下面这样写也是可以的
btn.onclick = function(e) {
e = e || window.event ;
};
//获取事件目标
btn.onclick = function(event) {
event = eventUtil.getEvent(event);
var target = eventUtil.getTarget(event);
};
//取消事件的默认行为
var link = document.getElementById("myLink");
link.onclick = function(e) {
e = e || window.event;
eventUtil.preventDefault(e);
};
//阻止事件冒泡(因为IE不支持事件捕获)
var btn = document.getElementById("myBtn");
btn.onclick = function(e) {
alert("Clicked");
e = e || window.event;
eventUtil.stopPropagation(e);
};
document.body.onclick = function(event) {
alert("Body Clicked");
};
重点:还有
事件委托也很重要!!!!