1

DOM事件

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

DOM事件流

DOM处理事件的流程

事件传递的3个过程

  • 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中是这样的

// 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)

触发事件

某些情况下,我们需要手动触发事件

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

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


小熊苗苗
328 声望18 粉丝

如果你的才华还实现不了你的野心,那就静下心来,埋头苦干


引用和评论

0 条评论