事件流:从页面中接受事件的顺序
事件冒泡(IE):事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接受,然后逐级向上传播到较不具体的文档节点(文档)
事件捕获:恰恰与事件冒泡相反,不太具体的节点应该更早接受到事件,而最具体的节点应该最后接受到事件(较少人使用)。
DOM2事件规定事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段
事件处理程序:响应某个事件的函数,以on
开头,例如onclick
,事件处理程序中的代码在执行过程中,有权访问全局作用域中的任何代码。this
对象指向事件的目标元素
<input type="button" value="click me" onclick="alert(this.value)">
DOM 0级事件处理程序
将一个函数赋给一个事件处理程序属性
var btn = document.getElementById("mybtn");
btn.onclick =function(){
alert("click");
};
btn.onclick = null; //删除事件
DOM 2级事件处理程序
addEventListener()
和removeEventListener()
(IE9+,及其他浏览器)
接受3个参数:要处理的事件名、作为事件处理程序的函数、一个布尔值(true表示在事件捕获阶段调用事件处理程序,而false代表在事件冒泡阶段调用事件处理程序)
btn.addEventListener("click",function(){alert("hello");},false);
- 通过
addEventListener()
添加的事件只能通过removeEventListener()
移除,且必须传入相同的参数,这意味着添加的匿名函数将无法移除
事件对象 Event
在触发DOM上的某个事件时,会产生一个事件对象Event,其包含了所有与事件相关的信息。
var btn = document.getElementById("mybtn");
btn.onclick =function(event){
alert(evnet.type); //click
};
event对象的一些属性和方法:
- target:事件的目标
- type:事件的类型
- preventDefault():取消事件的默认行为
- stopPropagation():取消事件的进一步捕获和冒泡
事件类型
UI事件
- load事件
当页面(也可以是图像、script元素、css文件)加载后,就会触发对应对象或元素(window / img / script / link)的load事件 unload事件
文档在完全卸载后触发(此时对象可能已不存在)resize事件
浏览器窗口大小发生变化时,在window上触发scroll事件
在窗口页面滚动时触发在window对象
焦点事件
blur事件
在元素失去焦点时触发focus
在元素获得焦点时触发
鼠标事件
- click事件
单击鼠标按钮或回车键 - dbclick事件
双击鼠标 - mousedown事件
按下任意鼠标按钮,不能通过键盘触发 - mousemove事件
当鼠标指针在元素内部移动时重复地触发 - mouseout事件
鼠标指针从一个元素移入另一个元素时触发 - mouseover事件
鼠标指针首次移入一个元素边界之内时触发 - mouseup事件
用户释放鼠标按钮时触发,不能通过键盘触发 - mousewheel事件
鼠标滚轮事件
坐标位置
鼠标的坐标位置保存在事件对象的属性中
- clientX 和 clientY:视口的水平坐标和垂直坐标
- pageX 和 pageY:相对于页面的水平坐标和垂直坐标,在没有滚动条的情况下,与clientX和clientY相等
- screenX 和 screenY:相对于屏幕的水平坐标和垂直坐标
修改键
同样保存在事件对象的属性中,当相应的键被按下时为true,否则为false
- shiftKey:对应
shift
键 - ctrlKey:对应
Ctrl
键 - altKey:对应
Alt
键 - metaKey:对应
windows
键等
鼠标按钮
针对mousedown
和mouseup
事件,确定是鼠标哪个键被按下和释放,值保存在event.button
属性中
- 0:左键
- 1:中间键(滚轮)
- 2:右键
鼠标滚轮
只针对mousewheel
事件,保存在event.wheelDelta
属性中,向前滚动是正数,向后滚动时负数
键盘和文本事件
- keydown事件
按下任意键触发,按住不放,则重复触发 - keypress事件
按下字符键时触发,按住不放,则重复触发 - keyup事件
释放按键时触发 - textinput事件
用户在可编辑区域中输入字符时,触发此事件
事件的发生顺序:keydown
▷ keypress
▷ keyup
在发生keydown和keyup事件时,event.keyCode
属性会包含一个键码,对应某个按键
在发生keypress事件时,event.charCode
属性会包含按下键的ASCII值
在发生textinput事件时,event.data
属性会包含用户输入的字符值
变动事件
当DOM中的某一部分发生变化时,触发的事件
- DOMSubtreeModified事件
当某节点的DOM子树结构发生任何变化时都会触发,这个事件在其他任何事件触发后都会触发 - DOMNodeRemoved事件
在节点从其父节点中被移除时触发(removeChild()
或replaceChild()
),event.target
属性指向被删除的节点 - DOMNodeInserted事件
在一个节点作为子节点被插入到另一个节点时触发(appendChild()
,replaceChild()
,insertBefore()
),event.target
属性指向插入的节点
HTML5事件
- contextmenu事件
实现单击右键,出现上下文菜单
div.addEventListener("contextmenu",function(event){
event.preventDefault(); //阻止默认的上下文菜单
var menu = document.getElementById("myMenu"); //选取自定义的菜单,比如一个<ul>元素
menu.style.visibility = "visible"; //使原本隐藏的菜单显现
});
window.addEventListener("click",function(event){
document.getElementById("myMenu").style.visibility = "hidden"; //单击其他地方将隐藏菜单
},false);
- beforeunload事件
在页面被卸载之前触发,询问用户是否卸载。必须将event.returnValue设置为要显示给用户的字符串,并作为函数值返回。
window.addEventListener("beforeunload",function(event){
var message = "DO YOU GO?";
event.returnValue = message;
return message;
},false);
DOMContentLoaded事件
在形成完整的DOM树之后即触发,不必等待CSS、JS等文件的加载完成,触发在load事件之前。pageshow 和 pagehide事件
在页面显示时触发,无论该页面是否来自bfcache(前进、后退按钮),这两个事件只能被添加到window对象上- haschange事件
当页面的URL参数列表发生变化时,就会触发。这个事件必须被添加到window对象上
内存和性能
事件委托
利用事件冒泡,只需指定一个事件处理程序,就可以管理某一类型的所有事件。节约了内存
<ul id="mylist">
<li id="1">1</li>
<li id="2">2</li>
<li id="3">3</li>
</ul>
var list = document.getElementById("mylist"); //获取列表
list.addEventListener("click",function(event){ //将事件添加到列表中
switch(evnet.target.id){ //根据列表项的id来判断
case "1":
//do something
break;
case "2":
//do something
break;
case "3":
//do something
break;
}
},false);
移除事件处理程序
当移除DOM某元素时,不要忘记将其绑定的事件处理程序移除
someElement.onclick = null;
模拟事件
模拟用户操作触发事件,步骤:创建event对象 ▷ 初始化event对象 ▷ 触发事件
创建event对象
var event = document.createEvent(事件类型)
//事件类型包括:UIEvents、MouseEvents、MutationEvents(变动事件)、HTMLEvents、KeyEvents等
初始化event对象
每个不同类型的事件对象,都具有一个初始化方法,指定触发的事件具体类型,该如何触发事件,是否冒泡等
//鼠标事件对象的初始化
event.initMouseEvent("click",true,true,document.defaultView,0,0,0,0,0,false,false,false,false,0,null);
触发事件
var btn = document.getElementById("mybtn");
btn.dispatchEvent(event); //触发事件