Правильное использование addEventListener()/attachEvent()?

Мне интересно, как правильно использовать addEventListener соответственно attachEvent?

window.onload = function (myFunc1) { /* do something */ }

function myFunc2() { /* do something */ }

if (window.addEventListener) {
  window.addEventListener('load', myFunc2, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', myFunc2);
}

 // ...

или

function myFunc1() { /* do something */ }

if (window.addEventListener) {
  window.addEventListener('load', myFunc1, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', myFunc1);
}

function myFunc2() { /* do something */ }

if (window.addEventListener) {
  window.addEventListener('load', myFunc2, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', myFunc2);
}

 // ...

?

Является ли этот кросс-браузер безопасным, или мне лучше пойти с чем-то вроде этого:

function myFunc1(){ /* do something */ }
function myFunc2(){ /* do something */ }
// ...

function addOnloadEvent(fnc){
  if ( typeof window.addEventListener != "undefined" )
    window.addEventListener( "load", fnc, false );
  else if ( typeof window.attachEvent != "undefined" ) {
    window.attachEvent( "onload", fnc );
  }
  else {
    if ( window.onload != null ) {
      var oldOnload = window.onload;
      window.onload = function ( e ) {
        oldOnload( e );
        window[fnc]();
      };
    }
    else
      window.onload = fnc;
  }
}

addOnloadEvent(myFunc1);
addOnloadEvent(myFunc2);
// ...

И: Скажите myfunc2 только для IE 7. Как правильно изменить правильный/предпочтительный метод?

Ответ 1

Использование обоих одинаково, хотя оба имеют немного другой синтаксис для параметра события:

addEventListener (ссылка mdn):

obj.addEventListener('click', callback, false);

function callback(){ /* do stuff */ }

Список событий для addEventListener.

attachEvent (ссылка MSDN):

obj.attachEvent('onclick', callback);

function callback(){ /* do stuff */ }

Список событий для attachEvent.

аргументы

Для обоих методов аргументы таковы:
1. Является ли тип события.
2. Является ли функция для вызова после запуска события.
3. (только addEventListener) Если true, указывает, что пользователь желает инициировать захват.

объяснение

Оба метода используются для достижения одной и той же цели - прикрепления события к элементу.
Разница в том, что attachEvent можно использовать только в старых механизмах рендеринга трезубцев (IE5+ IE5-8 *), а addEventListener - это стандарт W3, который реализован в большинстве других браузеров (FF, Webkit, Opera, IE9+),

Для надежной поддержки событий между браузерами, включая нормализации, которые вы не получите с помощью решения Diaz, используйте платформу.

* IE9-10 поддерживает оба метода для обратной совместимости.

Спасибо Люку Пуплетту за указание на то, что attachEvent был удален из IE11.

Минимальная кросс-браузерная реализация

Как рекомендовал Смитти, вы должны взглянуть на этот Dustin Diaz addEvent для надежной кросс-браузерной реализации без использования фреймворка:

function addEvent(obj, type, fn) {
  if (obj.addEventListener) {
    obj.addEventListener(type, fn, false);
  }
  else if (obj.attachEvent) {
    obj["e"+type+fn] = fn;
    obj[type+fn] = function() {obj["e"+type+fn](window.event);}
    obj.attachEvent("on"+type, obj[type+fn]);
  }
  else {
    obj["on"+type] = obj["e"+type+fn];
  }
}

addEvent( document, 'click', function (e) {
  console.log( 'document click' )
})

Ответ 2

Любой, кто все еще участвует в этом обсуждении и не находит ответ, который они искали:
http://dustindiaz.com/rock-solid-addevent

Это одно из самых элегантных решений, которые я нашел для тех из нас, у кого есть ограничения на использование фреймворков.

function addEvent(obj, type, fn) {

    if (obj.addEventListener) {
        obj.addEventListener(type, fn, false);
        EventCache.add(obj, type, fn);
    } else if (obj.attachEvent) {
        obj["e" + type + fn] = fn;
        obj[type + fn] = function() {
            obj["e" + type + fn](window.event);
        }
        obj.attachEvent("on" + type, obj[type + fn]);
        EventCache.add(obj, type, fn);
    } else {
        obj["on" + type] = obj["e" + type + fn];
    }

}

var EventCache = function() {

    var listEvents = [];
    return {
        listEvents: listEvents,
        add: function(node, sEventName, fHandler) {
            listEvents.push(arguments);
        },
        flush: function() {
            var i, item;

            for (i = listEvents.length - 1; i >= 0; i = i - 1) {
                item = listEvents[i];
                if (item[0].removeEventListener) {
                    item[0].removeEventListener(item[1], item[2], item[3]);
                };

                if (item[1].substring(0, 2) != "on") {
                    item[1] = "on" + item[1];
                };

                if (item[0].detachEvent) {
                    item[0].detachEvent(item[1], item[2]);
                };

                item[0][item[1]] = null;
            };
        }
    };
}();

addEvent(window, 'unload', EventCache.flush);