首先先来4段javascript代码,比较一下他们有什么不一样
1、原生js onclick来绑定事件,结果:只弹一次,B
是因为原生js 同一个dom同一事件绑定多次会被覆盖
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<button type="submit" class="login" id="btn">确定</button>
<script type="text/javascript">
var btn= document.getElementById("btn");
btn.οnclick=function (){
alert('A');
}
btn.οnclick=function (){
alert('B');
}
</script>
</body>
</html>
2、原生js 用attachEvent/addEventListener添加的同名事件,结果:弹2次,分别是A、B是因为用attachEvent/addEventListener添加的同名事件不会被覆盖
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<button type="submit" class="login" id="btn">确定</button>
<script type="text/javascript">
btn.addEventListener('click',function(){
alert('A');
})
btn.addEventListener('click',function(){
alert('B');
})
</script>
</body>
</html>
3、用jq click绑定事件,结果:弹2次,分别是A、B是因为jquery将绑定的事件放在数组里,触发事件时循环调用这个数组(原因是jquery库是用了addEventListener来绑定事件的)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<button type="submit" class="login" id="btn">确定</button>
<script src="jquery-1.11.1.min.js"></script>
<script type="text/javascript">
$("#btn").click(function(){
alert('A');
});
$("#btn").click(function(){
alert('B');
});
</script>
</body>
</html>
4、用 jq on()方法绑定事件,结果:弹2次,分别是A、B是因为用on()添加的同名事件不会被覆盖(我猜它的原理是跟用addEventListener来绑定事件是一样的)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<button type="submit" class="login" id="btn">确定</button>
<script src="jquery-1.11.1.min.js"></script>
<script type="text/javascript">
$('#btn').on('click',function(){
alert('A');
});
$('#btn').on('click',function(){
alert('B');
});
</script>
</body>
</html>
发现真的很神奇,然后我开始了各种百度,发现网上关于这部分的回答实在太少了下面是关于原生js添加的同名事件会被覆盖和attachEvent/addEventListener添加的同名事件不会被覆盖的解释:
因为直接将一个函数(function)对象,赋值给一个onclick属性,那此时onclick就指向了这个函数,后面再给这个onclick属性赋值的时候,onclick就指向了后面的那个函数了,也就出现了覆盖的情况,第一个函数就会在后面被垃圾回收掉。
在通常情况下,如果要为单个事件注册多个事件处理程序,那么只有最后注册的那个事件处理程序才会起作用。这是因为在DOM中,为HTML元素的一个事件指定事件处理程序时,这个事件处理程序会成为该元素的一个属性,如果为一个属性赋值,这个属性就会有这个值,可是如果再继续为这个属性赋值呢?很简单,这个属性就会有新值,原来的值就被覆盖了。所以,只有最后注册的那个事件处理程序才会起作用。为了解决这个问题,我们可以使用DOM Level 2模型的addEventListener()方法。
addEventListener("事件名(不用加on)",事件处理程序,Bool(指示是完成事件浮升(false)还是事件捕获(true),通常情况下使用false))。这个事件是DOM Level 2模型的新方法,所以支持该模型的浏览器都可以使用这个方法,但是,在ie浏览器中,并不支持addEventListener方法,不过不用担心,我们可以使用attachEvent("事件名(加on)",事件处理程序),作用是一样的。
使用了事件监听之后,我们并不能确定事件处理程序的调用顺序与其增加顺序一致,因为事件监听者并不会以某种特定的顺序调用事件处理程序,我们要确保事件处理程序不依赖于所调用的顺序。