再次學習了一下js的事件,把一些值得記住的要點寫下來,方便日後查詢。
首先要說一下typeof這個關鍵詞,此次才發現它是多麼的有用。它主要用於測試一個變量的類型,比如是string,number,function等等,但我說它好用還有另外的方面,就是它能夠測試一個對象,一個對象的變量等是否存在,如果不存在則會返回"undefined",則可以讓我們處理一些瀏覽器的兼容性問題。下面將會用到它。
由於有時我們想對某個事件添加兩個處理函數,但是如果直接用類似如下方式是不行的。document.getElementById(“test”).οnclick=function(){},如果有多個這樣的行爲則最後一個會覆蓋前面的。解決此類方法可以用w3c標準方法addEventListener,但是ie卻不支持此方法,ie的替換方案是使用attachEvent,舉個例子。
<html>
<head>
<title>javascript事件測試</title>
<script type="text/javascript">
window.onload = function(){
var target = document.getElementById("link");
if(typeof target.addEventListener != "undefined"){
target.addEventListener("click",function(){
alert("new a click");},false);
}else if(typeof target.attachEvent != "undefined"){
target.attachEvent("onclick",function(){
alert("new a click");});
}
}
</script>
<style rel="stylesheet" type="text/css">
</style>
</head>
<body οnclick="alert('body click...')">
<div οnclick="alert('div click')">
<a href="#" id="link" οnclick="alert('a click');">點我</a>
</div>
</body>
</html>
上面的代碼不管是在ie還是在firefox下當你點擊鏈接時都會彈出四次窗口來。能夠增加監聽處理函數,勢必就可以減少,addEventListener對應的是removeEventListener,而attachEvent對應的是detachEvent,這裏不再舉例。
如果細心觀察便會發現上邊的addEventListener多了最後一個boolean參數,當該值爲true時,表示處於capture狀態,爲false時表示處理bubble狀態。有何區別呢?capture狀態下,事件的傳遞方向是父節點>子節點傳遞的,而bubble則是子節點->父節點傳遞的。(我在ie6和firefox3.6中發現capture都沒效)如果你想取消這種傳遞的話,那麼也是有辦法的。W3c模型中,可以用stopPropagation()函數,而ie中可以用cancelBubble=true;再看如下代碼
<html>
<head>
<title>javascript事件測試</title>
<script type="text/javascript">
window.onload = function(){
var target = document.getElementById("link");
if(typeof target.addEventListener != "undefined"){
target.addEventListener("click",function(event){
alert("new a click");
event.stopPropagation();
},false);
}else if(typeof target.attachEvent != "undefined"){
target.attachEvent("onclick",function(){
alert("new a click");
window.event.cancelBubble = true;});
}
}
</script>
<style rel="stylesheet" type="text/css">
</style>
</head>
<body οnclick="alert('body click...')">
<div οnclick="alert('div click')">
<a href="#" id="link" οnclick="alert('a click');">點我</a>
</div>
</body>
</html>
現在當點擊的時候,只會彈出兩個單擊事件了,因爲取消了傳遞性。
關於上面的例子,還有一個要說明的是event的由來。如果是ie的話那麼event統一爲window.event,也就是說不用傳參數給處理函數,而比如firefox則是通過參數方式直接傳給處理函數。
通過監聽器方式添加處理函數,默認情況下,儘管你編寫了自己的處理函數,但是還會有其它默認的行爲發生,比如,你用監聽方式給一個表單添加了處理事件,儘管最後返回false該表單還是會照着action的路徑提交的,想要阻止這種行爲也是可以實現的。
在ie中,可以通過event.returnValue = false來實現,而firefox一類的瀏覽器可以通過執行event.preventDefault();來實現。看個例子
<html>
<head>
<title>javascript事件測試</title>
<script type="text/javascript">
window.onload = function(){
var myform = document.forms[0];
if(typeof myform.addEventListener != "undefined"){
myform.addEventListener("submit",function(event){
alert("submit");
event.preventDefault();
},false);
}else if(typeof myform.attachEvent != "undefined"){
myform.attachEvent("onclick",function(){
alert("submit");
window.event.returnValue = false;});
}
}
</script>
<style rel="stylesheet" type="text/css">
</style>
</head>
<body>
<form action="http://www.baidu.com" method="post">
<input type="submit" value="提交" />
</form>
</body>
</html>
上面的代碼在點擊按鈕後是不會進行提交的,如果想測試提交情況的話,可以把returnValue變爲true(針對ie),或者去掉event.preventDefault();這行代碼。(針對firefox)
關於事件還有好多需要注意的地方,不過只記一下比較基本的東西。
最後總結一下:
1. Typeof ;檢查對象或方法等是否存在,用”undefined”進行判斷
firefox類 vs ie類
2.addEventListener vs attachEvent ;添加處理函數
3. removeEventListener vs detachEvent ;移除處理函數
4. event.stopPropagation() vs cancelBubble=true ;取消事件傳遞
5. event.preventDefault() vs event.returnValue = false ;取消本事件的默認行爲