详解js中on和addEventListener用法
js中on和addEventListener都是用来做事件绑定。下面我们来看一下它们的用法和区别在哪里。
1.on的用法
这里面的on并不是jquery里面的on方法,而是on+“事件”。
如:onclick/ondbclick
onkeyup(是在用户放开任何先前按下的键盘键时发生 )
onkeydown(用户按下没有放开任何按键,包括系统键时发生)
onkeypress(按下并放开字母键,不包括系统键时发生)
onmousemove/onmouseover/ommousedown/onmouseout
/onmouseup(释放)
onchang
onsubmit
写法:obj.onclick= function(){}
2.addEventListener的用法
写法:
addEventListener(event,funtionName,useCapture)
参数:
event:事件的类型,不加on
funtionName:方法名
useCapture(可选):布尔值,指定事件是否在捕获或冒泡阶段执行,默认冒泡。
false-代表在冒泡阶段
true - 代表在捕获阶段
举个🌰
<div id="warper">1
<div id="inner">2
<div id="content">
3
</div>
</div>
</div>
function fn1(){alert(1);}
function fn2(){alert(2);}
function fn3(){alert(3);}
warper.addEventListener("click",fn1,false);
inner.addEventListener("click",fn2,false);
content.addEventListener("click",fn3,false);
由上面例子,点content弹出3、2、1
warper.addEventListener("click",fn1,false);
inner.addEventListener("click",fn2,true);
content.addEventListener("click",fn3,true);
如果把后两个false改成true,此时点content又会弹什么呢?
对这个时候页面弹的是2、3、1
总结一下,就是如果useCapture值是true,是在捕获阶段执行,我们都知道捕获行为是由上往下,而冒泡阶段是自下往上,当绑定的事件存在useCapture是true时,先执行是true的事件,然后按照捕获和冒泡行为的顺序。上面的代码很容易理解了吧~
事件流的三个阶段:冒泡阶段、捕获阶段、目标阶段
下图是事件流
document代表的是整个html页面,
document.documentElement代表是的<html>标签。
document.body代表的是<body>标签。
当ie9以下不支持addEventListener的时候,我们可以用attchEvent
obj.addEvent(event,funtionName);
参数:
event:事件类型(需要加on)
funtionName:方法名
ie不支持捕获
整合以下兼容代码
function addEvent(element,type,fn){ //绑定事件
if(element.addEventListener){ // IE9以下不兼容
element.addEventListener(type,fn,false)
}else if(element.attachEvent){ //IE独有
element.attachEvent('on' + type , function () {
fn.call(element);
//因为attachEvent方法在使用时,内部的this指向的是window,不方便,所以有时候要把这里的this变成自身
})
}else{
element['on'+type] = fn; //一个元素只能绑定一个处理程序
}
}
3.解绑事件-removeEventListener/detachEvent
function removeHandler(element,type,fn){ //移除事件
if(element.removeEventListener){
element.removeEventListener(type,handler,fn)
}else if(element.detachEvent){
element.detachEvent('on' + type,fn)
}else{
element['on' + type ] = null;
}
}
4.阻止事件冒泡和捕获-stopPropagation()
阻止事件的继续传播。
🌰
function fn3(event){
event.stopPropagation();
alert(3);
}
warper.addEventListener("click",fn1,false);
inner.addEventListener("click",fn2,true);
content.addEventListener("click",fn3,true);
此时点击content,弹出的是2、3,后面的1由于被阻断了,所以后面的内容不会被弹出了。
不过event.stopPropagation()
函数并不会阻止当前函数内部的执行。
IE下用:cancelBubble = true;
function stopProp(){
var ev = event||window.event;
if (ev.stopPropagation){
ev.stopPropagation();
}else{
ev.cancelBubble=true;
}
}
这里在说一下"event.preventDefault"和"return false"
event.preventDefault
:阻止事件的默认行为
IE下用:returnValue=false;
function stopDefault() {
var ev = event||window.event;
if (ev.preventDefault){
ev.preventDefault();
}else{
ev.returnValue=false;
}
}
return false
:相当于同时调用event.stopPropagation()
和event.preventDefault()
5.on和addEventListener区别:
1.一个元素绑定多个相同的事件,后面的事件会覆盖掉之前的事件。
2.addEventListener则不会覆盖。
6.加一个移动端禁止触发事件(这个在我们写移动端页面的时候,常会用到)
function preHandler(event){
event.preventDefault();
}
function addTouch(){//禁止
document.documentElement.addEventListener('touchmove',preHandler,false,{ passive: false });
}
function removeTouch(){//启用
document.documentElement.removeEventListener('touchmove',preHandler,false,{ passive: false });
}