JavaScript 事件监听 addEventListener
addEventListener()的工作原理是将实现EventListener的函数添加到调用它的EventTargrt上的指定事件类型的事件侦听器列表中。
1、事件监听 addEventListener (IE8及以下有兼容问题)
语法:ele.addEventListener(event_type , function ,布尔值(是否启用事件捕获去触发事件))
1. 第一个参数是事件的类型(比如"click"鼠标单击事件);
2. 第二个参数是在事件发生时我们要调用的函数;
3. 最后一个参数为可选参数,不写时默认false(即事件冒泡)。
【注意】事件监听中,请勿对事件类型event_type使用 "on" 前缀。比如要使用 "click" 代替 "onclick"。
1 <button id="btn">点我一下试试</button> 2 <script> 3 var btn_ele = document.getElementById("btn"); 4 btn_ele.addEventListener("click" , function(){ 5 alert("事件监听,你点击了按钮"); 6 }); 7 </script>
2、移除监听 removeEventListener
语法:ele.removeEventListener(事件类型,function)
传统事件绑定(DOM0)和事件监听器绑定(DOM2)的区别
1 <button id="btn">点我一下试试</button> 2 <script> 3 var btn_ele = document.getElementById("btn"); 4 5 // 事件绑定 6 btn_ele.onclick = function(){ 7 alert("事件绑定,你点击了按钮"); 8 } 9 // 事件监听 10 btn_ele.addEventListener("click" , function(){ 11 alert("事件监听,你点击了按钮"); 12 }); 13 </script>
DOM0 事件绑定
1.一个元素上只能有一个事件处理函数,容易删除;
1 btn_ele.onclick = function(){ 2 alert("事件绑定,你点击了按钮"); 3 // 想让事件只执行一次,添加下面这句话即可 4 btn_ele.onclick = null; 5 }
缺点:事件处理函数难以分割,存在覆盖问题,容错率低。
1 btn_ele.onclick = function(){ 2 alert("事件绑定,你点击了按钮1"); 3 } 4 btn_ele.onclick = function(){ 5 alert("事件绑定,你点击了按钮2");//只弹出2,2把1覆盖了 6 }
2.onclick的事件触发顺序是不可改变的,只能以冒泡的顺序进行传播。
1 btn_ele.onclick = function(){ 2 alert("button事件绑定,你点击了按钮"); 3 } 4 document.onclick = function(){ 5 alert("document事件绑定,你点击了按钮");//冒泡:从里到外触发,先触发button、再触发document的 6 }
----------------------------------------
DOM2 事件监听
1. 允许向一个元素添加多个相同事件,同时不覆盖已有事件;
即一个事件可以存着多个事件处理函数,容错率更高。
1 btn_ele.addEventListener("click" , function(){ 2 alert("事件监听,你点击了按钮1"); 3 }); 4 btn_ele.addEventListener("click" , function(){ 5 alert("事件监听,你点击了按钮2");//点一次按钮,会弹窗两次,即1和2 6 });
向一个元素添加不同类型的事件当然也允许啦。
2. 删除监听时,需要用到API removeEventListener();
1 btn_ele.addEventListener("click" , function(){ 2 alert("事件监听,你点击了按钮"); 3 // arguments.callee代表当前函数 4 btn_ele.removeEventListener("click" , arguments.callee); 5 // 此时 监听在执行一次后被删除 6 });
考虑到严格模式禁用callee属性,我们可以将单独函数提出来:
1 btn_ele.addEventListener("click" , clickHandler); 2 function clickHandler(){ 3 "use strict" 4 alert("事件监听,你点击了按钮"); 5 btn_ele.removeEventListener("click" , clickHandler); 6 }
3. 事件监听可以改变事件流的触发顺序;
——第3个参数为true时事件捕获,false时事件冒泡
1 btn_ele.addEventListener("click" , function(){ 2 alert("button事件监听,你点击了按钮"); 3 },true); 4 document.addEventListener("click" , function(){ 5 alert("document事件监听,你点击了按钮"); 6 },true); 7 // true为事件捕获,从外往里逐个触发。即先触发document,再触发button
冒泡和捕获是事件传播的2种方式
事件冒泡,是事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。浏览器默认事件冒泡。
简单来说,事件冒泡是由内向外的事件传播方式,而事件捕获是从外往里逐个触发。
事件监听的主动触发 dispatchEvent()
API: dispatchEvent(event); 在对应的元素上触发一个事件
1. 创建一个新的事件对象; var e = new Event("event_type");
2. 触发事件 : dispatchEvent(e) ;
1 btn_ele.addEventListener("click" , function(){ 2 console.log("btn_ele 事件监听主动触发") 3 }); 4 // btn_ele.onclick();//无法触发onclick。报错btn_ele.onclick is not a function 5 // 如何主动触发? 6 // 自己创建一个事件对象,去触发这个事件处理函数 7 var e = new Event("click"); 8 // btn_ele.dispatchEvent(e); 9 // 如果是类似轮播图效果 可以加定时器 10 setInterval(function(){ 11 btn_ele.dispatchEvent(e); 12 },1000)
监听器的兼容问题
IE8及其更早版本不支持 addEventListener() 和 removeEventListener() 方法。
不过,对于这些特殊的浏览器版本,可以使用 attachEvent() 方法向元素添加事件处理程序,并由 detachEvent() 方法删除。
【注意】使用attachEvent时,事件类型要加"on"前缀。
下面是事件监听的兼容写法:
1 // IE8的监听器写法 2 // document.attachEvent("onclick" , function(){ 3 // alert("hello world"); 4 // }); 5 // 移除监听是detachEvent 6 7 // 兼容写法如下 8 // 事件监听 : 9 function on( ele , type , callback ){ 10 if(typeof ele.addEventListener === "function"){ 11 ele.addEventListener( type , callback ); 12 }else{ 13 ele.attachEvent("on" + type , callback); 14 } 15 } 16 // 移除监听 : 17 function off( ele , type , callback ){ 18 if(typeof ele.removeEventListener === "function"){ 19 ele.removeEventListener( type , callback ); 20 }else{ 21 ele.detachEvent("on" + type , callback); 22 } 23 }