js和HTML之间交互是通过事件实现的。事件会有事件流。事件描述的是从页面接受事件的顺序。IE和网景提出了差不多相反的事件流概念。IE提出事件冒泡流。网景提出事件捕获流。
事件冒泡:事件开始时由最具体的元素接收,然后逐级向上传播到较不具体的节点。所有现代浏览器几乎都支持冒泡。
事件捕获:不具体的节点更早的接收事件,最具提的节点最后接收到事件。IE9以上可以支持捕获。
DOM2级规定的事件流包括三个阶段(IE8及更早版本不支持事件流):
- 事件捕获阶段
- 处于目标阶段
- 事件冒泡阶段。
事件处理程序:
- HTML事件处理程序
- DOM0级事件处理程序
- DOM2级事件处理程序
HTML事件处理程序
function clickMe (){
alert('hi')
} //这种处理程序代码耦合度太高,修改时需要修改两处。存在时差问题,有些事件可能需要HTML元素一出现在页面上就触发,但当时的事件处理程序可能尚不具备条件。
DOM0级事件处理程序:
var btn =document.getElementById('btn')
btn.onclick = function () {//每个事件只支持一个事件处理程序
alert('hi')
}
btn.onclick = null //删除事件处理程序
DOM2级事件处理程序:IE9及以上支持
使用DOM2级事件处理程序的好处是可以为一个元素绑定多个事件处理程序
var btn =document.getElementById('btn')
btn.addEventListener('click',function(){
alert('hi')
},false) //click事件在冒泡阶段触发
IE事件处理程序:IE8及以下只支持事件冒泡
var btn =document.getElementById('btn')
btn.attachEvent('onclick',funtion(){ //第一个参数为onclick,并不是click。
alert('hi') //attachEvent()添加的事件处理程序都会被添加到冒泡阶段
})
在IE中使用attachEvent()与使用DOM0级方法的主要区别:事件处理程序运行的作用域不一样。DOM0级事件处理程序会在其所属元素的作用域下运行,而attachEvent()的事件处理程序会在全局作用域运行。attachEvent()也可以为一个元素添加多个事件处理程序,执行顺序与DOM2级事件处理程序的执行顺序相反。
跨浏览器事件处理程序
var EventUtil = {
addEvent:function (element,type,handler) {
if (element.addEventListener) { //ie9及以上
element.addEventListener(type,handler, false)
} else if (element.attachEvent) { //ie8及以下
element.attachEvent('on'+type,handler)
} else {
element['on'+type] = handler
}
},
removeEvent:function(element, type,handler) {
if (element.removeEventListener) {//ie9及以上
element.removeEventListener(type,handler, false)
} else if (element.detachEvent) { //ie8及以下
element.detachEvent('on'+type,handler)
} else {
element['on'+type] = null
}
}
}
var btn =document.getElementById('btn')
var handler = function () {
alert('hi')
}
EventUtil.addEvent(btn,'click',handler)
EventUtil.removeEvent(btn,'click',handler)
事件对象
在触发DOM上的某个事件时,会产生事件对象event。这个对象包含与这个事件有关的信息。
DOM中的事件对象
兼容DOM的浏览器会将一个event对象传入到事件处理程序中,无论是DOM0级还是DOM2级。
var btn = document.getElementByid('btn')
btn.onclick = function (event) {
alert(event.type) //click
}
btn.addEventListener('click',function (event) {
alert(event.type) //click
}, false)
- cancelable 表示是否可以取消事件的默认行为
- preventDefault() 阻止默认操作 cancelable属性需要设置为true
- bubbles 表示事件是否冒泡
- stopPropagation() 取消事件的捕获或冒泡。如果bubbles为true
- event.target 时间的目标
- event.type 事件类型
- event.currentTarget 正在处理事件的元素
- event.eventPhase 确定事件当前正处于事件流的那个阶段 1表示捕获阶段 2 处于目标对象上 3 冒泡阶段
只有在事件处理程序执行期间,event对象才会存在,一旦事件处理程序执行完成,event对象就会被销毁
IE中的事件对象
要访问IE中的event对象有几种不同的方式,取决于事件处理程序的方法。DOM0级事件处理程序,event对象作为window属性存在。
使用attachEvent()的情况下,可以使用event对象,也可以通过window 对象来访问event对象
- cancelBubble 默认值是false,设置为true可以取消冒泡 与stoppropagation()作用相同
- returnValue 默认是false,设置为true表示取消事件默认行为 与* preventDefault()作用相同
- srcElement 事件的目标 与target属性相同
- type 事件类型
btn.onclick = function () {
alert (window.event.srcElement === this) //true
}
btn.attachEvent('onclick', function (event) {
alert(event.srcElement === this) //false
})
跨浏览器事件对象
var EventUtil = {
addEvent: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
}
},
removeEvent: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
}
},
getEvent: function (event) {
return event ? event : window.event
} ,
getTarget: function (event) {
return event.target || event.srcElement
},
preventDefault: function (event) {
if (event.preventDefault) {
event.preventDefault ()
} else {
event.returnValue = false
}
},
stopPropagation: function (event) {
if (event.stopPropagation) {
event.stopPropagation ()
} else {
event.cancelBubble = true
}
}
}
btn.onclick = function (event) {
event = EventUtil.getEvent (event)
var target = EventUtil.getTarget (event)
EventUtil.preventDefault()
EventUtil.stopPropagation()
}
事件类型
UI事件(用户与页面上的元素交互时触发)/ 焦点事件 /鼠标事件 /滚动事件/键盘事件/文本事件/变动事件/合成事件
UI事件指的是那些不一定与用户操作有关的事件。
- load事件 页面完全加载后window上触发
- unload事件 页面完全卸载后window上触发,只要用户从一个页面切换到另一个页面就会触发
- abort事件 用户停止下载过程时,如果嵌入的内容没有加载完
- error事件 当js发生错误时触发 当无法加载图片时在img上触发 当无法加载嵌入的内容时在
- select事件 当用户选中文本框中的一个或多个字符时触发
- resize事件 当窗口或框架的大小变化时在window或框架上触发
- scroll事件 当用户滚动带滚动条的元素中的内容时在该元素上触发
- load事件中:图片img可以实现预加载,新图像元素不一样要等到添加到文档后才开始加载,只要设置了它的src属性就会开始下载。而