JavaScript 與 HTML 之間的交互是通過事件實(shí)現(xiàn)的土铺。事件最早是在 IE3 和Netscape Navigator 2 中出現(xiàn)的,當(dāng)時(shí)是作為分擔(dān)服務(wù)器運(yùn)算負(fù)載的一種手段。在 IE4 和 Navigator 4 發(fā)布時(shí)吃引,這兩種瀏覽器都提供了相似但不相同的 API佛析,這些 API 并存經(jīng)過了好幾個(gè)主要版本。DOM2級規(guī)范開始嘗試以一種符合邏輯的方式來標(biāo)準(zhǔn)化 DOM 事件闯参。IE9瞻鹏、Firefox、Opera鹿寨、Safari 和 Chrome 全都已經(jīng)實(shí)現(xiàn)了“DOM2 級事件”模塊的核心部分新博。IE8 是最后一個(gè)仍然使用其專有事件系統(tǒng)的主要瀏覽器。
事件流
“DOM2級事件”規(guī)定的事件流包括三個(gè)階段:事件捕獲階段脚草、處于目標(biāo)階段和事件冒泡階段赫悄。IE9、Opera馏慨、Firefox埂淮、Chrome 和 Safari 都支持 DOM 事件流;IE8 及更早版本不支持 事件捕獲写隶。
事件處理程序
有四種指定事件處理程序的方法
- 使用HTML屬性指定倔撞,如:
// 使用這種方式指定事件處理程序的話,相當(dāng)于將onclick屬性值作為一段js代碼包裹在一個(gè)函數(shù)里面然后指給該元素對象的onclick屬性
// 該函數(shù)內(nèi)部有一個(gè)局部變量event
<button type="button" onclick="alert(event.type)">click me</button>
// 也可以在里面執(zhí)行其他函數(shù)慕趴,在該函數(shù)內(nèi)部可以訪問全局作用域里的其他函數(shù)
<button type="button" onclick="showMessage()">click me</button>
// 這個(gè)動(dòng)態(tài)創(chuàng)建的函數(shù)使用with擴(kuò)展作用域
// with語句的作用就是在代碼塊內(nèi)部訪問變量時(shí)痪蝇,現(xiàn)將其看作局部變量,如果找不到秩贰,就在傳入的參數(shù)對象內(nèi)部查找該屬性
function(){
with(document){
with(this){
//元素屬性值
}
}
}
// 因此下面的innerText === this.innerText
<button type="button" onclick="alert(innerText)">click me</button>
// 如果當(dāng)前元素是一個(gè)表單輸入元素霹俺,則作用域中還會(huì)包含訪問表單元素的入口,這個(gè)函數(shù)就變成了如下所示:
function() {
with(document) {
with(this.form) {
with(this) {
//元素屬性值
}
}
}
}
// 這樣的下面的代碼就可以理解了
form method="post">
<input type="text" name="username" value="">
<input type="button" value="Echo Username" onclick="alert(username.value)">
</form>
- DOM0級指定方法
var btn = document.getElementById("myBtn");
// 這種方法比較簡單毒费,在冒泡階段觸發(fā)丙唧,不過不能為同一個(gè)元素添加多個(gè)事件處理程序
btn.onclick = function() {
alert(this.id); //"myBtn"
};
//刪除事件處理程序
btn.onclick = null;
- DOM2級指定方法(IE9以上)
var btn = document.getElementById("myBtn");
// 第三個(gè)參數(shù)為true,表示在捕獲階段觸發(fā)觅玻,一般不使用
btn.addEventListener("click", function(e) {
alert(this.id);
}, false);
// 主要好處是可以添加多個(gè)事件處理程序想际,會(huì)按照添加它們的順序觸發(fā)
// 移除時(shí)傳入的參數(shù)要與添加處理程序時(shí)使用的參數(shù)相同。這也意味著匿名函數(shù)將無法移除
var btn = document.getElementById("myBtn");
var handler = function(){
alert(this.id);
};
btn.addEventListener("click", handler, false);
btn.removeEventListener("click", handler, false); //有效溪厘!
- IE8及以下使用的方法
// 只支持冒泡階段觸發(fā)胡本,第一個(gè)參數(shù)和DOM2相比多了'on'
var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function(){
// this指向window而不是元素本身
alert(this === window); //true
alert("Clicked");
});
// 也可以用來為一個(gè)元素添加多個(gè)事件處理程序,不過不是以添加它們的順序執(zhí)行畸悬,而是以相反的順序被觸發(fā)侧甫。
// 和DOM2一樣,匿名函數(shù)將無法移除
事件對象
一些比較重要的屬性
- currentTarget:代表被觸發(fā)事件處理程序的那個(gè)元素
- target:代表事件的實(shí)際目標(biāo),一次交互只會(huì)有唯一一個(gè)目標(biāo)
- eventPhase:1-捕獲階段 2-處于目標(biāo)上 3-冒泡階段
- preventDefault():取消事件的默認(rèn)行為
- stopPropagation():取消事件的進(jìn)一步捕獲或冒泡
IE的事件對象的一些比較重要的屬性
- srcElement:等于target
- cancelBubble:默認(rèn)為false披粟,但將其設(shè)置為true就可以取消事件冒泡(與stopPropagation()方法的作用相同咒锻,不過只能取消冒泡)
- returnValue:默認(rèn)為true,但將其設(shè)置為false就可以取消事件的默認(rèn)行為(與preventDefault()方法的作用相同)