3

可能重复:
使用 addEventListener 有什么区别?

我注意到可以直接在对象上分配事件,而无需使用 addEventListener:

document.onload = function(e){
  // do stuff..
};

代替:

document.addEventListener('load', function(e){
  // do stuff..
});

那么有什么理由我不应该使用第一种方法吗?为什么其他人不使用它?

这似乎也适用于旧 IE(您需要 attachEvent)。

4

2 回答 2

8

考虑如果您尝试以下操作会发生什么(我将事件附加到,window因为这是您应该监听此事件的地方)

window.onload = function (e) {console.log('A');};
window.onload = function (e) {console.log('B');};

对比

window.addEventListener('load', function (e) {console.log('C');}, false);
window.addEventListener('load', function (e) {console.log('D');}, false);

在第一个代码块中,您只会看到"B",但从第二个代码块中,您会同时看到"C""D"小提琴(请打开控制台查看)。

于 2012-12-28T12:01:32.520 回答
3

除了正如公认的答案所显示的那样,直接将处理程序绑定到 DOM 限制了处理程序的数量之外,addEventListener还有很多东西可以提供:
事件侦听器不需要直接绑定到元素(它不必存在于 DOM 中)。这在使用 ajax 时很有用(将其视为 jQuery 的.on方法)。
单个侦听器可以处理特定类型的所有事件,因此使用事件侦听器需要更少的资源(这可以加快整体性能)
对于 X 浏览器的兼容性(如 IE8),避免内存泄漏要容易得多:

window.onload = function(e)
{
    alert('In IE8, this causes mem-leaks!');
};


var load = function(e)
{//cf @PaulS.'s comment & link on IE8 and symbol bleeding
    e = e || window.event;//X-browser stuff
    var target = e.target || e.srcElement;//so you can use this callback for all browsers
    if (window.removeEventListener)
    {//more X-browser stuff
        return window.removeEventListener('load',load,false);
    }
    window.detachEvent('onload',load);//reference callback by variable name
};
if (window.addEventListener)
{
    window.addEventListener('load',load,false);
}
else
{//in IE8, addEventListener doesn't exist, but it has a jScript counterpart:
    //no mem-leaks in IE AFAIK
    window.attachEvent('onload', load);
}

这里有几个你可能会感兴趣的链接(是的,我知道,无耻的自我推销——对不起):

为什么我们需要事件监听器?
IE8 中的内存泄漏和事件委托和关闭

只是为了好玩:我不久前编写的一个脚本,它使用事件委托并适用于 IE、FF、chrome触摸设备。这比我预期的要棘手一些。

/**
* Copyright 2012, Elias Van Ootegem
* Date: Tue Jul 03 2012 +0100
*/
(function(G,undef)
{
    'use strict';
    var load,clickHandler,touchHandler,hide,reveal;
    hide = function(elem)
    {
        elem.setAttribute('style','display:none;');
    };
    reveal = function(show,nextTo)
    {
        var str = 'display: block; position:relative; left:220px; top: ' + (nextTo.offsetTop - show.parentNode.offsetTop) + 'px;';
        show.setAttribute('style',str);
    }
    load = function()
    {
        var doc = G.document;
        if (G.removeEventListener)
        {
            G.removeEventListener('load',load,false);
        }
        else
        {
            G.detachEvent('onload',load);
        }
        if (doc.hasOwnProperty('ontouchstart'))
        {//We have a touch device
            touchHandler = (function(subNavs)
            {
                var current,divs = (function()
                {
                    var i,r = {};
                    for (i=0;i<subNavs.length;i++)
                    {
                        r[subNavs[i].id] = doc.getElementById(subNavs[i].id + 'd');
                        hide(r[subNavs[i].id]);
                    }
                    return r;
                }());
                return function(e)
                {
                    e = e || G.event;
                    if (e.changedTouches.length !== 1)
                    {//multi-touch
                        return e;
                    }
                    var timer,endListener,coords,target = e.target || e.srcElement;
                    if (target.tagName.toLowerCase() === 'img' && target.id.match(/^close[0-9]+$/))
                    {
                        hide(current);
                        current = undef;
                        return e;
                    }
                    if (target.tagName.toLowerCase() === 'a')
                    {
                        target = target.parentNode;
                    }
                    if (target.tagName.toLowerCase() !== 'p' || !target.id || !divs[target.id])
                    {
                        if (current === undef)
                        {
                            return e;
                        }
                        while(target !== doc.body)
                        {
                            target = target.parentNode;
                            if (target === current)
                            {
                                return e;
                            }
                        }
                        timer = setTimeout(function()
                        {
                            doc.body.removeEventListener('touchend',endListener,false);
                            clearTimeout(timer);
                            timer = undef;
                        },300);
                        endListener = function(e)
                        {
                            doc.body.removeEventListener('touchend',endListener,false);
                            clearTimeout(timer);
                            timer = undef;
                            hide(current);
                            current = undef;
                            return e;
                        };
                        return doc.body.addEventListener('touchend',endListener,false);
                    }
                    coords = {x:e.changedTouches[0].clientX,y:e.changedTouches[0].clientY};
                    timer = setTimeout(function()
                    {
                        doc.body.removeEventListener('touchend',endListener,false);
                        clearTimeout(timer);
                        timer = undef;
                    },300);
                    endListener = function(e)
                    {
                        e = e || G.event;
                        clearTimeout(timer);
                        timer = undef;
                        doc.body.removeEventListener('touchend',endListener,false);
                        var endCoords,endTarget = e.target || e.srcElement;
                        if (endTarget !== target)
                        {
                            endCoords = {x:e.changedTouches[0].clientX,y:e.changedTouches[0].clientY};
                            if (Math.abs(coords.x - endCoords.x) < 26 && Math.abs(coords.y - endCoords.y) < 26)
                            {
                                endTarget = target;
                            }
                        }
                        if (endTarget !== target)
                        {
                            return e;
                        }
                        if (current !== undef)
                        {
                            hide(current);
                            current = undef;
                        }
                        current = divs[target.id];
                        reveal(current,target);
                    };
                    doc.body.addEventListener('touchend',endListener,false);
                };
            }(doc.getElementsByClassName('subnavbar')));
            return doc.body.addEventListener('touchstart',touchHandler,false);
        }
        clickHandler = (function(subNavs)
        {
            var current,divs = (function()
            {
                var i,r = {};
                for (i=0;i<subNavs.length;i++)
                {
                    r[subNavs[i].id] = doc.getElementById(subNavs[i].id + 'd');
                    hide(r[subNavs[i].id]);
                }
                return r;
            }());
            return function(e)
            {
                e = e || G.event;
                var target = e.target || e.srcElement;
                if (target.tagName.toLowerCase() === 'img' && target.id.match(/^close[0-9]+$/))
                {
                    hide(current);
                    current = undef;
                    return e;
                }
                if (target.tagName.toLowerCase() === 'a')
                {
                    target = target.parentNode;
                }
                if (target.tagName.toLowerCase() !== 'p' || !target.className.match(/\bsubnavbar\b/))
                {
                    if (current !== undef)
                    {
                        target = (function()
                        {
                            while (target !== doc.body)
                            {
                                target = target.parentNode;
                                if (target === current)
                                {
                                    return current;
                                }
                            }
                        }());
                        if (target !== current)
                        {
                            hide(current);
                            current = undef;
                        }
                    }
                    return e;
                }
                if (e.preventDefault)
                {
                    e.preventDefault();
                    e.stopPropagation();
                }
                else
                {
                    e.returnValue = false;
                    e.cancelBubble = true;
                }
                if (current !== undef)
                {
                    hide(current);
                }
                current = divs[target.id];
                reveal(current,target);
            };
        }(doc.getElementsByClassName('subnavbar')));
        if (doc.body.addEventListener)
        {
            return doc.body.addEventListener('click',clickHandler,false);
        }
        return doc.body.attachEvent('onclick',clickHandler);
    };
    if (G.addEventListener)
    {
        return G.addEventListener('load',load,false);
    }
    return G.attachEvent('onload',load);
}(this));
于 2012-12-28T12:48:25.950 回答