示例代码:
<div class="爷爷">
<div class="爸爸">
<div class="儿子">文字div>
div>
div>
即.爷爷>.爸爸>.儿子, 给3个div分别添加事件监听fnYe/fnBa/fnEr
提问1: 点击了谁?
点击文字, 算不算点击儿子
点击文字, 算不算点击爸爸
点击文字, 算不算点击爷爷
答: 都算
提问2: 调用顺序? 点击文字最先调用fnYe/fnBa/fnEr中的哪一个函数?
答: 都行. IE5调用顺序为fnEr->fnBa->fnYe, 网景调用顺序为fnYe->fnBa->fnEr
因此W3C在2002年发布了标准, 文件名为DOM Level 2 Events Specification, 规定浏览器同时支持两种调用顺序.首先按爷爷->爸爸->儿子顺序看有没有函数监听, 然后按儿子->爸爸->爷爷顺序看有没有函数监听.
因此, 用专业术语来说这2种顺序分别就是DOM事件模型的事件捕获和事件冒泡.一个事件发生后,会在子元素和父元素之间传播(propagation)。
由外向内找监听函数, 叫事件监听.
由内向外找监听函数, 叫事件冒泡.
其中文字(示例代码中)就是事件监听和事件冒泡的目标.因此DOM事件模型分为3个阶段:
(1)捕获阶段:事件从window对象自上而下向目标节点传播的阶段(示例代码中简化为: 爷爷->爸爸->儿子);
(2)目标阶段:真正的目标节点正在处理事件的阶段;(示例代码中: 文字)
(3)冒泡阶段:事件从目标节点自下而上向window对象传播的阶段(示例代码中简化为: 儿子->爸爸->爷爷)。
事件绑定:
IE5: baba.attachEvent('onclick', fn)
//事件冒泡
网景: baba.addEventListener('click', fn)
//事件捕获
W3C: baba.addEventListener('click', fn, bool)
, 如果bool不传或为falsy, 则fn使用事件冒泡, 反之则fn使用事件捕获.
DOM级别一共可以分为四个级别:DOM0级、DOM1级、DOM2级和DOM3级。而DOM事件分为3个级别:DOM 0级事件处理,DOM 2级事件处理和DOM 3级事件处理。由于DOM 1级中没有事件的相关内容,所以没有DOM 1级事件。
var btn = document.getElementById('btn');
btn.onclick = function(){
alert(this.innerHTML);
}
当希望为同一个元素/标签绑定多个同类型事件的时候(如给上面的这个btn元素绑定3个点击事件),是不被允许的。DOM0事件绑定,给元素的事件行为绑定方法,这些方法都是在当前元素事件行为的冒泡阶段(或者目标阶段)执行的。
var btn = document.getElementById('btn');
btn.addEventListener("click", test, false);
function test(e){
e = e || window.event;
alert((e.target || e.srcElement).innerHTML);
btn.removeEventListener("click", test)
}
//IE9-:attachEvent()与detachEvent()。
//IE9+/chrom/FF:addEventListener()和removeEventListener()
IE9以下的IE浏览器不支持 addEventListener()和removeEventListener(),使用 attachEvent()与detachEvent() 代替,因为IE9以下是不支持事件捕获的,所以也没有第三个参数,第一个事件名称前要加on。
UI事件,当用户与页面上的元素交互时触发,如:load、scroll
焦点事件,当元素获得或失去焦点时触发,如:blur、focus
鼠标事件,当用户通过鼠标在页面执行操作时触发如:dblclick、mouseup
滚轮事件,当使用鼠标滚轮或类似设备时触发,如:mousewheel
文本事件,当在文档中输入文本时触发,如:textInput
键盘事件,当用户通过键盘在页面上执行操作时触发,如:keydown、keypress
合成事件,当为IME(输入法编辑器)输入字符时触发,如:compositionstart
变动事件,当底层DOM结构发生变化时触发,如:DOMsubtreeModified
同时DOM3级事件也允许使用者自定义一些事件。