再次学习了一下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 ;取消本事件的默认行为