关于事件兼容性

DOM事件

事件咱们常常用到,用起来也比较简单,今天咱们主要聊一下DOM事件流、事件的兼容性、事件代理。javascript

DOM事件流

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
    }
}

事件相关的知识点仍是比较清晰的,实际使用时,善用事件代理哦!

相关文章
相关标签/搜索