JS与HTML通过事件交互。事件,就是文档或浏览器窗口发生的一些特定的交互瞬间。可以使用侦听器(或处理程序)来预订事件,以便事件发生时执行相应的代码。这种在传统工程中被称为观察员模式的模型,支持页面的行为(JS)与页面的外观(HTML和CSS)之前的松散耦合。
13.1事件流
事件流描述的是从页面中接受事件的顺序。
IE事件流是事件冒泡流,而网景事件流是事件流捕获流。
13.1.1事件冒泡
即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。
div->body->html->document
IE9、Firefox、Chrome和Safari则讲事件一直冒泡到window对象。
13.1.2事件捕获
事件捕获的思想是从不太具体的节点更早接收时间,而最具体节点应该最后接收到事件。用意在于事件到达预订目标之前捕获它。
documengt->html->body->div
13.1.3DOM事件流
DOM2级事件规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。
13.2事件处理程序
事件就是用户或浏览器自身执行的某种的动作。而响应某个事件的函数为事件处理程序或事件侦听器。事件处理程序的名字以on开头,如onclick/onload/onmouseover...
13.2.1HTML事件处理程序
事件处理程序使用一些js代码作为值来定义,因此不能在其中使用未经转义的HTML语法字符,列如&、””、<、>。如果要使用双引号则"
function showMessage(){}
这样指定事件处理程序会创建一个封装着元素属性值的函数,这个函数有一个局部变量event,也就是事件对象
在这个函数内部,this值等于事件的目标元素。
关于这个动态创建的函数,它扩展了作用域。
function(){
with(document){
with(this){
//元素的属性值
}
}
}
13.2.2DOM0级事件处理程序
// this引用当前元素
let btn = document.getElementById('myBtn')
btn.onclick = function(){
alert(this.id)
}
// 删除事件处理程序
btn.onclick = null
13.2.3DOM2级事件处理程序
addEventListener()、removeEventListener()
三个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值(true为捕获阶段调用,false为冒泡阶段调用)
btn.addEventListener('click',function(){},false)
通过addEventListener()添加的事件处理程序只能使用removeEventListener()来移除,移除时传入的参数与添加处理程序时使用的参数相同。意味添加的匿名函数无法移除。
let handler = function(){}
btn.addEventListener('click',handler,false)
btn.removeEventListener('click',handler,false)
13.2.4IE事件处理程序
btn.attachEvent("onclick",function(){})
btn.deleteEvent("onclick",function(){})
注意是onclick不是click
13.2.5跨浏览器事件处理程序
13.3事件对象
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。列如,鼠标操作导致的事件对象中会包含鼠标位置的信息,而键盘操作导致的事件对象中会包含与按下的键有关的消息。
13.3.1DOM中的事件对象
btn.onclick = function(event){
alert(event.type) // 'click'
}
event对象包含与创建它的特定事件有关的属性和方法。
在事件处理程序内部,对象this===currentTarget,而target则只包含事件的实际目标。
如果事件处理程序在目标元素上,则this,cuttentTarget和target相同。
btn.onclick=function(event){
// event.currentTarget=event.target=this
}
body.onclick=function(event){
// event.currentTarget=this=document.body
// event.target=document.getElementById('myBtn')
}
preventDefault()方法
阻止特定事件的默认行为。cancelable属性为true才可以用preventDefault()来取消起默认行为。
stopPropagation()
立即停止事件在DOM层次中的传播
eventPhase属性
用来确定事件当前处于事件流的哪个阶段
1为捕获
2为处于目标对象上
3为冒泡
btn.onclick=function(event){
alert(event.eventPhase) // 2
}
document.body.addEventListener('click',function(){
alert(event.eventPhase) // 1
},true)
document.body.onclick=function(event){
alert(event.eventPhase) // 3
}
13.3.2IE中的事件对象
DOM0级添加的事件event对象作为window对象的一个属性存在
btn.onclick=function(event){
// event==window.event
}
13.3.3跨浏览器的事件对象
13.4事件类型
13.4.1UI事件
UI事件指的是那些不一定与用户操作有关的事件。
1. load事件
当页面完全加载后(包括所有图像、JS文件、CSS文件等外部资源),就会触发window上面的load事件。有两种定义onload事件的方式
- js形式
EventUtil.addHandler(window,'load',function(event){alert('Loaded!')})
- Html形式
上可以加onload
2.unload事件
在文档被完全卸载后触发。只要用户从一个页面切换到另一个页面,就会发生unload事件。利用该事件可以清除引用,避免内存泄漏。
既然unload事件是在一切都被卸载之后才触发,那么在页面加载后存在的那些对象,此时就不一定存在了,此时,操作DOM节点或者元素的样式都会导致错误。
3. resize事件
当浏览器窗口被调整到一个新的高度或宽度时,就会触发resize事件。这个事件在window上触发,因此可以通过JS或者body元素中的onresize特性来指定事件处理程序。
IE,Safari、Chrome、Opera窗口变化了1像素就触发
4. scroll事件
在混杂模式下,可以通过body元素的scrollLeft和在srollTop来监控这一变化。
在标准模式下,除Safari(根据body)所有其他浏览器都通过元素来反映这一变化。
在文档被滚动期间重复触发。
13.4.2焦点事件
焦点事件会在页面元素获得或失去焦点是触发。利用这些事件并与document.hasFocus()方法及document.activeElement属性配合,可以知晓用户在页面上的行踪。
blur
在元素失去焦点时触发。这个事件不会冒泡,所有浏览器都支持。
focus
在元素获得焦点触发。这个事件不会冒泡,所有浏览器都支持。
focusin
在元素获得焦点时触发,冒泡。IE、Safari、Opera、Chrome
focusout
在元素失去焦点时触发,冒泡。IE、Safari、Opera、Chrome
13.4.3鼠标滚轮事件
click
单击主鼠标按钮或者按下回车键时触发
dblclick
双击主鼠标按钮时触发
mousedown
按下任意鼠标按钮时触发,不能通过键盘触发这个事件
mouseup
在用户释放鼠标按钮时触发。不能通过键盘触发这个事件
mouseenter
在鼠标光标从元素外部首次移动到元素范围之内时触发。不冒泡,而且在光标移动到后代元素上不触发。
mouseleave
在位于元素上方的鼠标移动到元素范围之外时触发,不冒泡,而且在光标移动到后代元素上不触发。
mousemove
当鼠标指针在元素内部移动时重复触发,不能通过键盘触发。
mouseout
在鼠标指针位于一个元素上方,然后用户将其移入另一个元素时触发。不能通过键盘触发
mouseover
在鼠标指针位于一个元素外部,然后用户将其首次移入另一个元素边界之内触发。不能通过键盘触发。
除了mouseenter和mouseup其他都冒泡,也可以取消,但是取消鼠标事件将会影响浏览器的默认行为。
只有在同一个元素上触发mousedow和mouseup事件,才会触发click事件,若其中一个被取消,就不会出发click事件。dblclick类似。
触发顺序如下
Mousedown
Mouseup
Click
Mousedown
Mouseup
Click
Dblclick
可以用一下代码检验浏览器是否支持上面的事件
Let isSupported = document.implementation.hasFeature(‘MouseEvents’,’2.0’)
Let isSupported = document.implementation.hasFeature(‘MouseEvent’,’3.0’)