事件是JavaScript和DOM之间进行交换的桥梁。事件就是用户或浏览器的某种行为,如点击、输入等等。
一、事件模型
存在三种模型,原始事件模型、DOM事件模型、IE事件模型。
原始事件模型被所有浏览器所支持,DOM事件模型被出IE6、7、8以外的所有主流浏览器支持,IE6、7、8支持IE事件模型。
1、原始事件模型
事件一旦发生就直接调用事件处理函数,事件不会向其他对象传播。事件程序的注册可以采用以下几种:
1、在HTML中设置对象属性
在HTML中直接添加事件属性,并将该属性值设置为js语句,如:
<input type = "button" value="确认" onclick = "alert('收到确认');">
其中,onclick表示点击事件发生时执行的js语句。js一般会写在一个函数中,把函数名绑定给事件属性,通过函数传参。如:
<input type = "button" value = "确认" onclick = "makeTrue(this)">
其中,makeTrue就是函数,传递了this代表事件发生的当前对象,即input对象。
2、在JavaScript中设置事件属性
首先要获取对象,然后给对象的事件属性值设置一个函数名称。
obj.eventType = handler;
//或者,事件属性值设置为一个匿名函数
obj.eventType = function(){···}
obj为要设置事件的对象,eventType是事件名称,handler是函数名称。当一个事件对应多个函数时,后一个函数会覆盖前一个函数。
<script>
window.onload = function(){
var bT = document.getElementById("bt");
bT.onclick = fn1;
bT.onclick = fn2;
}
fucntion fn1(){
alert("我被覆盖了!");
}
function fn2(){
alert("我被执行了!");
}
</script>
window对象的onload属性绑定一个匿名函数,这样保证网页中所有元素加载完毕后再去获取bT对象并注册事件。
3、使用代码触发事件
显式地触发事件,从而调用对应的事件处理程序。
<script>
function p(){
var f = window.confirm("are you sure?");
if(f){
document.getElementById("myform").submit();
}
else{
return false;
}
}
</script>
<body>
<form id = "myform" action = "x.html" >
<input type = "button" value = "submit" onclick = "return p()">
</form>
</body>
这种方法不会触发表单的onsubmit事件。显示是否确认提交的显示框,单击”取消“按钮,函数返回false,阻止submit按钮执行默认的提交动作,表单不会提交。如果将onclick = return p()改成了onclick = p(),当现实是否确认提交的显示框时,无论单击确定还是取消按钮,表单都要被提交。
html中设置事件属性时,常把事件的属性值设置为一个返回boolean值的return语句。如果return语句返回true,则执行该事件默认行为;如果返回false,则取消该事件默认行为。
使用代码触发事件的常用方法:
1)blur():使窗体或控件失去焦点,并触发onblur事件。
2)focus():使窗体或控件获得焦点,并触发onfocus事件。
3)click():触发onclick事件。
4)select():选取文本域内容,并触发onselect事件。
5)reset():重置表单,并触发onreset事件。
6)submit():提交表单,IE不会触发表单的onsubmit事件,其他浏览器会触发表单的onsubmit事件。
7)onsubmit():提交表单,触发表单的onsubmit事件。
2、DOM事件模型
DOM事件流:DOM是树形结构。当一个HTML元素产生一个事件时,该事件会在元素节点与根节点之间按特定的顺序传播,路径所经过的节点都会收到该事件。这个过程称为DOM事件流。事件流按传播顺序分为两种类型,即事件捕捉和事件冒泡。
事件捕捉:从最顶层元素document对象开始,一直传递到最精确的元素,相当于从根节点开始向叶子节点传递。
事件冒泡:从最精确的元素开始,一直传递到最顶层元素,相当于从叶子节点开始向根节点传递。
DOM事件模型同时支持事件捕捉和事件冒泡,事件捕捉先发生。两种事件流都会经过DOM中所有的对象,从document开始也在document对象结束。大部分兼容标准的浏览器会将事件捕捉或冒泡延续到window对象。
如果有一个事件处理函数既注册了捕获型事件的监听,又注册了冒泡型的事件监听,当对应事件发生时,它就会被调用两次。虽然所有的事件类型都会经历事件捕捉,但只有部分事件会经历冒泡阶段,如submit就不会冒泡。
DOM事件模型中事件处理程序的注册:
addEventListener("eventType",handler,true|false);
DOM事件模型中事件程序的删除:
removeEventListener("eventType",handler,true|false);
eventType:事件类型名;前缀on去掉,如:click。
handler:事件处理程序;
true|false:设置事件绑定的阶段,true是捕获阶段,false是冒泡阶段。addEventListener()支持给一个元素添加多个事件处理函数。
可以调用event.stopPropagation()或event.cancelBubble = true来停止事件传播。
可以调用event.preventDefault()来阻止浏览器的默认行为。
示例:
<script>
function initiate(){
var myButton = document.getElementById("myButton");
//myButton按钮上为click事件添加了两个函数
myButton.addEventListener("click",function(e){
alert(this.id);
},false);
myButton.addEventListener("click",funtion(e){
alert("Hi!");
},false);
}
//在window对象上为load事件添加了一个处理函数,为click事件添加了一个处理函数。
//绑定的事件处理函数可以是一个函数名称,如下面的initiate
window.addEventListener("load",initiate,false);
//绑定的事件处理函数也可以是一个匿名函数,如function(e){···}。
//函数参数e用于接收event对象。
window.addEventListener("click",funtion(e){
alert("window click");
},false);
</script>
<body>
<input type = "button" id = "myButton" value = "点击">
</body>
//绑定的事件处理函数可以是一个函数名称,如initiate。
运行这个程序时,点击按钮时,依次弹出”myButton“、”Hi!“、”window click“三个信息。也就是按钮上的单机事件冒泡延续到了window对象。如果不希望往上传递,则将click改写如下:
myButton.addEventListener("click",function(e){
alert(this.id);
e.stopPropagation();
},false);
此时再单机按钮,依次弹出”myButton“、”Hi!“两个信息。
调用删除函数removeEventListener时,传入的参数要与addEventListener时使用的参数相同,所以注册的匿名函数无法删除。要删除事件处理函数,如下:
var handler = funtion(){
alert(this.id);
};
myButton.addEventListener("click",handler,false);//绑定事件处理函数
myButton.removeEventListener("click",handler,false);//移除事件处理函数
<script>
var link = document.getElementById("link");
link.addEventListener("click",function(e){
alert("单击链接");
e.preventDefault();//阻止浏览器默认动作(页面跳转)
//如果没有这句代码,单击链接会弹出“单击链接”信息框,然后跳转“a.html”页面,叫上这句代码,只弹出信息框而不跳转。
},false);
</script>
<body>
<a href = "a.html" id = "link">点击链接</a>
</body>
3、IE事件模型
IE浏览器中的事件流仅包含冒泡阶段(IE6~IE8),在冒泡过程中,可以设置event.cancelBubble = true 来停止事件冒泡。
事件处理的注册:
attachEvent("eventType","handler");
IE事件模型中事件处理程序的删除:
detachEvent("eventType","handler");
eventType:事件类型名;前缀on不要去掉,如:onclick。
handler:事件处理程序。
冒泡过程中,若希望能从子节点直接跳转到指定节点,可调用fireEvent方法转发事件到指定对象:
fireEvent("eventType", [,oEventObject]);
eventType:事件类型名;
oEventObject:指定对象。
示例:
<script>
function initiate(){
var name1 = document.getElementById("n1");
var name2 = document.getElementById("n2");
var info = document.getElementById("info");
var myButton = document.getElementById("myButton");
if(name1.attachEvent){//IE方法
name1.attachEvent("onclick",function(){
info.innerHTML + = '红色' +'<br'>;
});
name2.attachEvent("onclick",function(){
info.innerHTML + = '绿色' + '<br>';
});
}
else{//DOM方法
name1.addEventListener("click",funtion(){
info.innerHTML + = '红色' +'<br'>
},false);
name2.addEventListener("click",funtion(){
info.innerHTML + = '绿色' +'<br'>
},false);
}
if(window.attachEvent){
window.attachEvent("onload",initiate);
}
else{
window.addEventListener("load",initiate,false);
}
}
</script>
<body>
<div id = "n1" style = "border:1px solid red;">点击</div>
<div id = "n2" style = "border:1px solid blue;">点点击</div>
<div id = "info"></div>
</body>
二、event对象
Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。事件通常与函数结合使用,函数不会在事件发生前被执行。
事件发生时,浏览器会自动创建一个event对象。事件处理函数通过event对象的属性来获取事件的类型、键盘按键状态、鼠标位置状态等信息。DOM事件模型中,event对象以函数参数的形式传入;IE事件模型中,event对象作为window对象的属性,通过window.event获取。通用事件处理函数:
function EventHandler(ev){
var e = ev || window.event;
//事件处理程序
}
其中,e为事件对象(兼容DOM和IE事件模型)。但是,DOM事件模型与IE事件模型的事件对象的属性也有大差异。如下。
1、DOM的event对象
DOM的event对象属性:http://www.w3school.com.cn/jsref/dom_obj_event.asp
常用属性:
- screenX / screenY: 事件发生时,鼠标在计算机屏幕中的x坐标和y坐标。event.screenX / event.screenY。
- pageX / pageY: 事件发生时,鼠标在网页中的x坐标和y坐标。
- clientX / clientY: 事件发生时,鼠标相对于浏览器窗口可视文档区域的中的x坐标和y坐标。不考虑文档的滚动情况。event.clientX / event.clientY。
- layerX / layerY: 事件发生时,鼠标在事件发生层中的x坐标和y坐标。
- currentTarget: 事件传播过程中事件所传播到的元素。在捕获和起泡阶段,该属性是非常有用的,因为在这两个节点,它不同于 target 属性。event.currentTarget。
- target: 触发该事件的对象。event.target。
- cancelBubble: 布尔值,true时,将停止事件进一步冒泡到更上层。e.cancelBubble。
- type: 事件类型,即当前 Event 对象表示的事件的名称。event.type。与注册的事件句柄同名,或者是事件句柄属性删除前缀 “on” 比如 “submit”、“load” 或 “click”。
- button: 返回一个整数,指示当事件被触发时哪个鼠标按键被点击。event.button=0|1|2(左|中|右)。
- which: 数值表示的键盘或鼠标键1|2|3(左|中|右)。
- keyCode: 对于 keypress 事件,该属性返回被敲击的键生成的 Unicode 字符码。对于 keydown 和 keyup 事件,它指定了被敲击的键的虚拟键盘码。虚拟键盘码可能和使用的键盘的布局相关。
<script type="text/javascript">
function show_coords(event)
{
x=event.screenX
y=event.screenY
alert("X coords: " + x + ", Y coords: " + y)
}
</script>
</head>
<body onmousedown="show_coords(event)">
<p>在文档中点击某个位置。消息框会提示出指针相对于屏幕的 x 和 y 坐标。</p>
</body>
2、IE的event对象
IE的event对象属性:http://www.w3school.com.cn/jsref/dom_obj_event.asp
常用属性:
- screenX / screenY: 事件发生时,鼠标在计算机屏幕中的x坐标和y坐标。event.screenX / event.screenY。
- clientX / clientY: 事件发生时,鼠标相对于浏览器窗口可视文档区域的中的x坐标和y坐标。不考虑文档的滚动情况。event.clientX / event.clientY。
- offsetX / offsetY: 事件发生时,鼠标相对于事件源元素的坐标系统中的x坐标和y坐标。
- x / y:事件发生时,鼠标相对于CSS动态定位的最内层包容元素的 x 坐标和 y 坐标。
- cancelBubble: 布尔值,true时,将停止事件进一步冒泡到更上层。e.cancelBubble。
- fromElement: 对于mouseover和mouseout事件,fromElement 引用移出鼠标的元素。
- srcElement: 对于生成事件的 Window 对象、Document 对象或 Element 对象的引用。
- toElement: 对于 mouseover 和 mouseout 事件,该属性引用移入鼠标的元素。
- returnValue: 如果设置了该属性,它的值比事件句柄的返回值优先级高。把这个属性设置为 fasle,可以取消发生事件的源元素的默认动作。
- keyCode: 对于 keypress 事件,该属性返回被敲击的键生成的 Unicode 字符码。对于 keydown 和 keyup 事件,它指定了被敲击的键的虚拟键盘码。虚拟键盘码可能和使用的键盘的布局相关。
3、HTML 5 事件属性
1、window事件属性
window事件由window对象触发,适用于body标签,window事件属性(句柄):http://www.w3school.com.cn/jsref/dom_obj_event.asp
常用属性: