事件咱们常常用到,用起来也比较简单,今天咱们主要聊一下DOM事件流、事件的兼容性、事件代理。javascript
DOM处理事件的流程java
事件传递的3个过程node
capture phase
:事件的捕获过程;从DOM
树的最顶端,直到捕获到出发这个事件的节点的父元素target phase
:事件的触发过程bubble phase
:事件的冒泡阶段,将会从当前节点的父节点开始,一直冒泡到window
对象这3个流程由W3C规定,可是在IE的低版本里并无第一个捕获的过程;
并非全部事件都有这3个过程,有些事件是没有冒泡的过程,例如页面load
事件没有冒泡过程。浏览器
注册事件、取消注册、触发事件、事件对象和事件源、阻止事件传播、取消默认行为等在IE浏览器中和其余浏览器是有区别的,下面咱们逐一来看一下函数
事件的注册常常用到,你们都是比较熟悉的,须要注意的是兼容性的问题。性能
// IE之外 // type 事件类型 // listener 事件处理函数 //最后一个参数可选的:若是是true那么事件句柄在在捕获节点执行;若是是false则事件句柄在冒泡阶段执行 elem.addaEventListener(type,listener [,useCapture]) // 实例 elem.addEventListener('click',clickhandler,false); function clickhandler(){ // do something }
而IE
中是这样的spa
// IE // type 事件类型 // listener 事件处理函数 // IE中没有捕获阶段 所以没有第三个参数 elem.attachEvent(type,listener); // 实例 elem.attachEvent('onclick',handler);//事件名称 含 'on' function handler(){ // do something }
咱们能够作一个兼容的方法,还比较容易理解的。代理
function addEvent(elem,type,listener){ if(elem.addEventListener){ elem.addEventListener(type,listener,false); } if(elem.attachEvent){ elem.attachEvent('on'+type,listener) } }
//接受参数和addEventListener一致 //IE之外 elem.removeEventListener(type,listener [,useCapture]); //IE elem.detachEvent(type,listener)
某些状况下,咱们须要手动触发事件code
//IE之外 elem.dispatchEvent(type); //触发button的click事件 button.dispatchEvent('click'); //IE elem.fireEvent(type); //触发button的click事件 button.fireEvent('onclick');
当调用事件处理函数时候,会隐形的传入一个对象,这个对象就含有了事件的一些状态和信息对象
function handler(e){ //获取事件对象 // IE的低版本,事件对象不是经过event传入的,而是放在window对象上面 e = event || window.event; //获取事件源 //IE下是 srcElement var target = e.target || e.srcElement; }
常规的点击连接会打开,可是有时候只是但愿处理自定义的业务逻辑而不是打开,这时咱们应该取消默认行为。
function eventHandler(e) { e = e || window.event; // 防止默认行为 if (e.preventDefault) { e.preventDefault();//IE之外 } else { e.returnValue = false;//IE //注意:这个地方是没法用return false代替的 } }
有时咱们须要阻止事件冒泡
function handler(e){ e = e || window.event; if(e.stopPropagation){ e.stopPropagation();//IE之外 }else{ e.cancelBubble = true;//IE } }
ul
下有多个li
,咱们想要实如今点击每一个li
的时候,都触发click
事件,若是在每一个li
上都绑定click
事件,工做量将会很大,且要维护多个函数,性能也比较差。这种状况下,咱们应该使用事件代理
//在ul上绑定事件,点击li时,经过冒泡传递到ul上,触发click事件 ul.addEventListener('click',handler,false); function handler(e){ e = e || window.event; var targetNode = e.target || e.srcElement; //判断点击的target子元素的类型来触发相应的事件 if(targetNode.nodeName.toLowerCase() === 'li'){ // dosomething } }
事件相关的知识点仍是比较清晰的,实际使用时,善用事件代理哦!