為節(jié)省頁面,所有代碼均寫在<body></body>內(nèi)。
事件
-
事件是文檔或?yàn)g覽器中發(fā)生的某些特定的交互瞬間。
JavaScript
和HTML
之間的交互都是通過事件。(拖動(dòng)滾動(dòng)條、鼠標(biāo)滑動(dòng)、點(diǎn)擊等) -
事件流:從頁面中接受事件的順序。
選擇某個(gè)按鈕同時(shí),也會(huì)觸發(fā)這個(gè)按鈕的容器,接著觸發(fā)上級(jí)容器,button-->div-->...-->body-->html-->document
(事件冒泡流)。
事件流的種類
-
事件冒泡流:指事件最開始由最具體的元素(文檔中嵌套層數(shù)最深的節(jié)點(diǎn))接收,然后逐級(jí)向上傳播至
document
節(jié)點(diǎn)。(IE8之前瀏覽器只支持事件冒泡,并且不支持DOM2級(jí)事件處理程序)
button-->div-->...-->body-->html-->document
-
事件捕獲:不太具體的節(jié)點(diǎn)最先接收到事件,最具體的節(jié)點(diǎn)最后接收到事件。(與事件冒泡流截然相反,老版本IE瀏覽器不支持事件捕獲,所以慎用,可以放心使用事件冒泡流模型)。
document-->html-->body-->...-->div-->button
- 實(shí)例
<html>
<head></head>
<body>
<div>
<input type = "button" id = "btn" onclick = "function() {}"/>
</div>
</body>
</html>
事件冒泡:瀏覽器會(huì)認(rèn)為在"onclick"
按鈕時(shí),先觸發(fā)按鈕的事件,再依次向上傳遞,觸發(fā)上級(jí)標(biāo)簽(parentNode
)綁定的事件。
- 阻止事件冒泡:
event.stopPropagation();
,(event
是一個(gè)事件對(duì)象) - 阻止事件的默認(rèn)行為:
event.preventDefault();
(阻止事件的默認(rèn)行為,類似a
標(biāo)簽的跳轉(zhuǎn)超鏈接)
事件處理程序
- HTML事件處理程序:直接在HTML標(biāo)簽內(nèi)添加事件。
<div>
<!--在html標(biāo)簽內(nèi)直接添加事件-->
<input type = "button" id = "btn" onclick = "showMes()"/>
</div>
<script>
function showMes()
alert("hello world");
}
</script>
缺點(diǎn):HTML與JavaScript代碼緊密耦合在一起,如果需要更改事件的處理方法,需要同時(shí)修改html
和js
中的代碼,不便于修改。不推薦使用
-
DOM0級(jí)事件處理程序:
傳統(tǒng)方式:將函數(shù)賦值給一個(gè)事件的處理程序?qū)傩浴?strong>使用較多,并且簡(jiǎn)單易用,跨瀏覽器
<input type="button" value="按鈕1" id="btn1" onclick="showMes()"> <!--html內(nèi)調(diào)用事件,不推薦使用-->
<input type="button" value="按鈕2" id="btn2">
<script>
var btn1 = document.getElementById("btn1");
var btn2 = document.getElementById("btn2");
//
function showMes() {
alert("hello world");
}
btn2.onclick = showMes; //將單擊事件屬性添加給按鈕2屬性,并且賦值為showMes
btn2.onclick = null; //不想要該事件時(shí),可以賦值null刪除事件
</script>
優(yōu)點(diǎn):只需在js
代碼中修改添加的事件,降低代碼的耦合,便于維護(hù)。注意btn2.onclick = showMes
,沒有括號(hào)。通過btn2.onclick = null;
刪除事件
-
DOM2級(jí)事件處理程序
DOM2級(jí)事件指定兩個(gè)方法:用于指定處理和刪除事件的操作。addEventListener(event,handler,bool)
和removerEventListener(event,handler, bool)
兩個(gè)方法。(所有DOM節(jié)點(diǎn)都包含這兩個(gè)方法,并且包含三個(gè)參數(shù),兩個(gè)方法的參數(shù)完全相同)。
event
:指需要處理的事件名,click
,mouseover
等,注意少了字符on
handler
:指作為事件處理程序的函數(shù),觸發(fā)相應(yīng)事件后運(yùn)行的js
函數(shù)。
bool
:true
表示采用事件捕獲模型(在捕獲階段調(diào)用事件處理程序),false
表示采用事件冒泡模型(在冒泡階段調(diào)用事件處理程序),由于通常使用事件冒泡模型,所有多數(shù)情況為false
(添加到冒泡階段可以兼容大多數(shù)瀏覽器)。
<input type="button" value="按鈕3" id="btn3">
<script>
var btn3 = document.getElementById("btn3");
//
function showMes() {
alert("hello world");
}
btn3.addEventListener("click", showMes, false); //去掉on
btn3.removeEventListener("click", showMes, false);
</script>
注意:去掉調(diào)用事件類型前的"on"
,只需要"click"
;通過addEventListener()
方法添加的事件 只能通過removerEventListener()
方法刪除,并且兩個(gè)方法中的參數(shù)相同。
通過DOM0級(jí)和DOM2級(jí)事件處理程序,可以為一個(gè)元素添加多個(gè)事件處理程序(也可以添加多個(gè)事件),按照添加的順序執(zhí)行。
<input type="button" value="按鈕3" id="btn3">
<script>
var btn3 = document.getElementById("btn3");
function showMes() {
alert("hello world");
}
//在一個(gè)元素上添加多個(gè)事件
btn3.addEventListener("click", showMes, false);
btn3.addEventListener("click", function() {
alert(this.value); //彈出按鈕3的value屬性。
}, false);
</script>
注:結(jié)果會(huì)一次彈出兩個(gè)窗口,先是showMes
窗口,單擊后再顯示匿名函數(shù)窗口。this
參數(shù)引用被觸發(fā)的元素。
IE事件處理程序
IE不支持addEventListener()
和removeEventListener()
兩個(gè)方法,它自定義attachEvent(event, handler)
和detachEvent(event, handler)
兩個(gè)方)法。接受相同的兩個(gè)參數(shù)(事件名稱,事件處理函數(shù)),IE默認(rèn)使用事件冒泡模型,所以不需要第三個(gè)布爾參數(shù)。
注:IE的event
參數(shù)需要加上"on"
,像"onclick"
、"onmouseover"
。
<input type="button" value="按鈕3" id="btn3">
<script>
var btn3 = document.getElementById("btn3");
function showMes() {
alert("hello world");
}
//在一個(gè)元素上添加多個(gè)事件,加上on
btn3.attachEvent("onclick", showMes);
btn3.detachEvent("onclick", function() {
alert(this.value); //彈出按鈕3的value屬性。
});
</scirp>
兼容IE的方法
由于IE和其他瀏覽器的DOM2級(jí)事件處理程序方法不同,需要做兼容性設(shè)置。采用恰當(dāng)?shù)臋z測(cè)來解決,最好將方法封裝在對(duì)象將對(duì)象賦值給變量方便調(diào)用。
<input type="button" value="按鈕3" id="btn3">
<script>
var btn3 = document.getElementById("btn3");
function showMes() {
alert("hello world");
}
//給對(duì)象封裝兩個(gè)方法,添加事件和刪除事件
var eventUtil = {
//添加事件
addHandler: function(element, event, handler) {
if(element.addEventListener){ //如果元素有封裝addEventListener方法
element.addEventListener(event, handler, false);
} else if(element.attachEvent) { //如果元素有封裝attachEvent方法
element.attachEvent("on"+event, handler); //注意IE需要加上'on'
} else {
element["on"+event] = handler; //不支持DOM2級(jí)的方法,使用DOM0級(jí)方法增加,并且使用方括號(hào),注意'on'
}
}, //注意逗號(hào)
//刪除事件
removeHandler: function(element, event, handler) {
if(element.removeEventListener){ //如果元素有封裝addEventListener方法
element.removerEventListener(event, handler, false);
} else if(element.detachEvent) { //如果元素有封裝attachEvent方法
element.detachEvent("on"+event, handler); //注意IE需要加上'on'
} else {
element["on"+event] = null; //不支持DOM2級(jí)的方法,使用DOM0級(jí)方法增加,并且使用方括號(hào),注意'on'
}
}
}
eventUtil.addHandler(btn3, "click", showMes); //傳入"click"
eventUtil.removeHandler(btn3, "click", showMes); //刪除事件
</scirp>
注意:兩個(gè)對(duì)象方法之間用,
隔開,傳入的參數(shù)使用"click",注意在不知道屬性名稱時(shí)使用方括號(hào)訪問。