关于JavaScript事件绑定的方式

JavaScript事件绑定 javascript

本文介绍一些JavaScript事件绑定的经常使用方法及其优缺点,同时在最后展现一个由 Dean Edwards 写的一个比较完美的事件绑定方案。 html


传统方式

element.onclick = function(e){ // ... };
  1. 传统绑定的优势
    • 很是简单和稳定,能够确保它在你使用的不一样浏览器中运做一致
    • 处理事件时,this关键字引用的是当前元素,这颇有帮组
  2. 传统绑定的缺点 
    • 传统方法只会在事件冒泡中运行,而非捕获和冒泡
    • 一个元素一次只能绑定一个事件处理函数。新绑定的事件处理函数会覆盖旧的事件处理函数
    • 事件对象参数(e)仅非IE浏览器可用

W3C方式

element.addEventListener('click', function(e){ // ... }, false);


  1. W3C绑定的优势
    • 该方法同时支持事件处理的捕获和冒泡阶段。事件阶段取决于addEventListener最后的参数设置:false (冒泡) 或 true (捕获)。
    • 在事件处理函数内部,this关键字引用当前元素。
    • 事件对象老是能够经过处理函数的第一个参数(e)捕获。
    • 能够为同一个元素绑定你所但愿的多个事件,同时并不会覆盖先前绑定的事件
  2. W3C绑定的缺点
    • IE不支持,你必须使用IE的attachEvent函数替代。

IE方式

element.attachEvent('onclick', function(){ // ... });
  1. IE方式的优势
    • 能够为同一个元素绑定你所但愿的多个事件,同时并不会覆盖先前绑定的事件。
  2. IE方式的缺点
    • IE仅支持事件捕获的冒泡阶段
    • 事件监听函数内的this关键字指向了window对象,而不是当前元素(IE的一个巨大缺点)
    • 事件对象仅存在与window.event参数中
    • 事件必须以ontype的形式命名,好比,onclick而非click
    • 仅IE可用。你必须在非IE浏览器中使用W3C的addEventListener

Dean Edwards的方案(addEvent/removeEvent库)


function addEvent(elementment, type, handler) {
    
        // 为每一个事件处理函数赋予一个独立的ID
        if(!handler.$$guid) handler.$$guid = addEvent.guid++;
    
        // 为元素创建一个事件类型的散列表
        if(!elementment.events) elementment.events = {};
    
        // 为每对元素/事件创建一个事件处理函数的散列表
        var handlers = elementment.events[type];
    
        if(!handlers) {
            handlers = elementment.events[type] = {};
            // 存储已有的事件处理函数(若是已存在一个)
            if(elementment["on" + type]) {
                handlers[0] = elementment["on" + type];
            }
        }
    
        // 在散列表中存储该事件函数
        handlers[handler.$$guid] = handler;
    
        // 赋予一个全局事件处理函数来出来全部工做
        elementment["on" + type] = handleEvent;
    }
    
    // 建立独立ID的计数器
    addEvent.guid = 1;
    
    function removeEvent(elementment, type, handler) {
        // 从散列表中删除事件处理函数
        if(elementment.events && elementment.events[type]) {
            delementte elementment.events[type][handler.$$guid];
        }
    }
    
    function handleEvent(event) {
        var returnValue = true;
    
        // 获取事件对象(IE使用全局的事件对象)
        event = event || fixEvent(window.event);
    
        // 获取事件处理函数散列表的引用
        var handlers = this.events[event.type];
    
        // 依次执行每一个事件处理函数
        for(var i in handlers) {
            this.$$handerEvent = handlers[i];
            if(this.$$handlerEvent(event) === fasle) {
                returnValue = false;
            }
        }
        return returnValue;
    }
    
    // 增长一些IE事件对象缺少的方法
    function fixEvent(event) {
        event.preventDefault = fixEvent.preventDefault;
        event.stopPropagation = fixEvent.stopPropagation;
        return event;
    }
    
    fixEvent.preventDefault = function() {
        this.returnValue = false;
    }
    
    fixEvent.stopPropagation = function() {
        this.cancelBubble = true;
    }





  1. addEvent的优势
    • 能够在全部浏览器中工做,就算是更古老无任何支持的浏览器
    • this关键字能够在全部的绑定函数中使用,指向的是当前元素
    • 中和了全部防止浏览器默认行为和阻止事件冒泡的各类浏览器特定函数
    • 无论浏览器类型,事件对象老是做为第一个对象传入
  2. addEvent的缺点
    • 仅工做在冒泡阶段(由于它深刻使用事件绑定的传统方式)
相关文章
相关标签/搜索