一、事件流
1、什么叫事件流
- 描述的是从页面接收事件的顺序;
2、事件冒泡(放心用,都支持)
- 事件开始由最具体的元素接收,然后逐级向上传播到较为不具体的节点;
3、事件捕获
- 事件开始由不太具体的元素接收,然后向下逐级传递给最具体的元素;
4、DOM2级事件流
- DOM2级事件流规定三个阶段:事件捕获阶段、出于目标阶段、时间冒泡阶段(规定的是事件捕获阶段不涉及时间目标,但是实际情况中所有浏览器在捕获阶段都触发了事件,结果造成有两个机会在目标对象上操作事件);
二、时间发生顺序
1、通过HTMl特性添加事件处理程序
<input type = "button" value="点击" onclick="alert("Hello World!")"/>
- 缺点一:时差问题;
- 缺点二:可能在访问非限定对象成员时出错;
- 缺点三:HTML和JavaScript代码紧密耦合;
2、DOM0级事件处理程序(元素的方法,this指向当前元素)
- 将一个函数赋值给一个事件处理程序属性
- 语法:
var btn = document.getElementById("myBtn");
btn.onclick = function(){
alert("this.id"); //myBtn
}
- 删除DOM0级方法指定的事件处理程序
btn.onclick = null
3、DOM2级事件处理程序
- 添加
var btn = document.getElementById("myBtn");
btn.addEventListener("click",function(){
alert(this.id); //myBtn
},false);//false表明事件在冒泡阶段触发
var btn = document.getElementById("myBtn");
var handler = function(){
alert(this.id); //myBtn
}
btn.addEventListener("click",handler,false);//false表明事件在冒泡阶段触发,默认值可省略
- 移除(移除时要与添加时传入相同的参数,匿名函数无法移除)
btn.removeEventListener("click",function(){
alert(this.id);
});//无效
btn.removeEventListener("click",handler,false); //移除成功
- 作用域同DOM0级事件处理程序,在其依附的元素的作用域中运行;
- IE:attachEvent()和detachEvent(),参数1为onclick;
- 优点:可同时为同一元素添加多个事件处理程序
4、跨浏览器的事件处理程序
- EventUtil对象
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;
}
}
};
//使用EventUtil对象
EventUtil.addEventListener(btn,"click",handler);
EventUtil.removeEventListener(btn,"click",handler);
三、事件对象
1、(非IE浏览器)无论以什么方式创建事件处理程序都会传入event对象,event对象包含与创建他的特定事件有关的属性和方法;
2、event对象常用的属性/方法
属性/方法 | 类型 | 读/写 | 说明 |
---|---|---|---|
cancelable | Boolean | 只读 | 表明是否可以取消事件的默认行为 |
currentTarget | Element | 只读 | 其事件处理程序正在处理事件的哪个元素 |
target | Element | 只读 | 事件的目标 |
type | String | 只读 | 被触发的事件类型 |
eventPhase | Integer | 只读 | 调用事件处理程序的阶段:1:捕获阶段;2:表示“出于目标”;3:表示冒泡阶段; |
perventDefault() | Function() | 只读 | 取消事件的默认行为;若cancelable是 |
true,则可使用这个方法 | |||
stopPropagation | function() | 只读 | 停止事件在DOM层次中的传播 |
3、使用event.type,使用同一函数处理多个事件
var a = document.getElementById("a");
var b = document.getElementById("b");
var c = document.getElementById("c");
var handler = function(event){
switch(event.type){
case "click":
alert("clicked");
break;
case "mouseover":
alert("mouseover");
break;
case "mouseout":
alert("mouseout");
break;
}
}
a.addEventListener("click",handler,false);
b.addEventListener("mouseover",handler,false);
c.addEventListener("mouseout",handler,false);
4、IE中的事件处理程序
- 使用HTML特性添加事件处理程序时:仍可以使用event对象访问
- 使用DOM0级别添加事件处理程序时:event对象属于window对象的一个属性,但是此时的event对象的属性/方法不同与其他浏览器,但是都包含cancleBubble、returnValue、SRCElement、type;
5、跨浏览器的事件对象
var EventUtil = {
addHandler:function(event){
return event?event:window.event;
},
getTarget:function(event){
return event.target?event.srcElement;
},
preventDefault:function(){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false;
}
},
removeHandler:fucntion(element,type,handler){
//省略代码
},
removePrepagation:function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
}
};
四、事件类型
1、事件类型有哪些?
DOM3级事件规定了9种事件
事件 | |
---|---|
UI(User Interface) | 当用户与页面上的元素交互时触发 |
焦点事件 | 元素获得或失去焦点时触发 |
鼠标事件 | 当用户通过鼠标在页面上执行操作时触发 |
滚轮事件 | 当时用鼠标滚轮(或类似设备)时触发 |
文本事件 | 当在文档中键入文本时触发 |
键盘事件 | 当用户通过键盘在页面上执行操作时触发 |
合成事件 | 当为IME(input method editor)输入字符时触发 |
变动事件 | 当底层DOM结构变化时触发 |
变动名称事件 | 丢弃 |
2、UI事件
- load事件:当页面完全加载后在window上触发;当框架完全加载后在框架集上触发;当图片完全加载完毕后再上触发;当嵌入的内容加载完毕后,在元素上触发;
- 定义onload事件的事件处理程序
//方法一:javascript方法
EventUtil.addHandler(window,"load",function(event){
alert("loaded");
})
//方法二:为元素添加onload特性
<body onload="alert('1')"></body>
- unload事件
//方法一:javascript方法
EventUtil.addHandler(window,,"unload",function(){
alert("unloaded");
})
//方法二:为元素添加onload特性
<body onunload="alert('unloaded')"></body>
- resize事件
EventUtil.addHandler(window,"resize",function(){
alert("resize");
})
- scroll事件
EventUtil.addHandler(window,"scroll",function(){
if(document.compatMode == "CSS1Compat"){
console.log("document.documentElement.scrollTop");
}else {
console.log("document.body.scrollTop");
}
})
3、焦点事件
- facus
- blur
- 判断浏览器是否支持事件
//判断浏览器是否支持blur/focus、DOMFocusOut/In 和 focusout/in
var issupport = document.implementation.hasFeature("FocusEvent","3.0")
4、鼠标事件与滚轮事件
- mousedown事件
- mouseup
- click
- dbclick
- 获取事件的客户端坐标信息
var div = document.getElementById("myDiv");
EventUtil.addHandler(div,"click",function(){
event = EventUtil.getEvent(event);
alert("Client coordinates"+event.clientX+","+event.clientY);
})
- 获取鼠标事件发生时鼠标指针相对于整个屏幕的坐标位置信息(screenX和screenY);
var div = document.getElementById("myDiv");
EventUtil.addHandler(div,"click",function(){
event = EventUtil.getEvent(event);
alert("Screen coordinates:")
})
-
修改键
表示修改键的状态(布尔值,按下为true)
shiftKey、ctrlkey、altkey、metaKey -
相关元素
var EventUtil = {
//省略其他代码
getRelatedTarget = function(event){
if(event.relatedTarget){
event.relatedTarget;
} else if(event.toElement){
event.toElement; //IE mouseout
} else {
event.fromElement; //IE mouseover
}
}
}
- 鼠标按钮
var EventUtil = {
//省略其他代码
getButton : function(event){
if(document.implementation.hasFeature("mouseEvents","2.0"))
return event.button;
} else {
switch(event.button){
case 0:
case 1:
case 3:
case 5:
case 7:
return 0;
case 2:
case 6:
return 2;
case 4:
return 1;
}
}
}
//使用
var div = document.getElementById("myDiv");
EventUtil.addHandler(div,"mouseDown",function(){
event = EventUtil.getEvent(event);
console.log(EventUtil.getButton(event));
})
- 鼠标滚轮事件
var EventUtil = {
getWheelDelta:function(event){
//省略了其他代码
if(event.wheelDelta){
return (client.engine.opera && client.engine.opera < 9.5 ?
-event.wheelDelta : event.wheelDelta);
}else {
return -event.detail * 40;
}
}
}
- 触摸设备
- 无障碍问题
5、键盘与文本事件
- 三个键盘事件
keydown、keypress、keyup - 一个文本事件
textInput
6、复合事件(缺少支持,用处不大)
7、变动事件
8、HTML5事件
9、设备事件 - window.orientationchange
10、触摸与手势事件
五、内存和性能
1、事件委托
<ul id="myLinks">
<li id="goSomewhere">Go somewhere</li>
<li id="doSomething">Do something</li>
<li id="sayHi">Say hi</li>
</ul>
var list = document.getElementById("myLinks");
EventUtil.addHandler(list,"click",function(){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
switch(target.id){
case "goSomewhere":
document.title = "I changed document's title";
break;
case "doSomething":
location.href = "http://www.baidu.com";
break;
case "sayHi":
console.log("HI!");
break;
}
});
2、移除事件处理程序