Javascript добавить события реализации кросс-браузерной функции: используйте attachEvent/addEventListener против встроенных событий

Чтобы добавить события, мы могли бы использовать это простое 1-е решение:

function AddEvent(html_element, event_name, event_function) 
{       
   if(html_element.attachEvent) //Internet Explorer
      html_element.attachEvent("on" + event_name, function() {event_function.call(html_element);}); 
   else if(html_element.addEventListener) //Firefox & company
      html_element.addEventListener(event_name, event_function, false); //don't need the 'call' trick because in FF everything already works in the right way          
} 

или это 2-е решение (которое добавляет встроенные события):

function AddEvent(html_element, event_name, event_function) 
{       
   var old_event = html_element['on' + event_name];
   if(typeof old_event !== 'function')
      html_element['on' + event_name] = function() { event_function.call(html_element); };
   else
      html_element['on' + event_name] = function() { old_event(); event_function.call(html_element); };
}

Оба являются кросс-браузерами и могут использоваться следующим образом:

AddEvent(document.getElementById('some_div_id'), 'click', function() 
{             
   alert(this.tagName); //shows 'DIV'
});  

Так как у меня есть чувство attachEvent/addEventListener мне интересно больше в реализации обработчиков событий:

Есть ли какие-либо недостатки / недостатки в использовании второго решения, о которых мне лучше знать?

Я вижу два, но меня интересует больше (если есть):

  1. 2-е решение запутывает innerHTML элементов, добавляя события inline
  2. Используя второе решение, я могу легко удалить все функции, связанные с определенным типом события (html_element['on' + event_name] = null), но я не могу использовать detachEvent/removeEventListener удалить именно определенную функцию.

Любые ответы, такие как "использовать jQuery" или любой другой FW, бессмысленны!

2 ответа

Решение

Со вторым решением вам придется вручную вызывать предыдущие функции, что затрудняет удаление определенных слушателей (что, на мой взгляд, звучит как то, что вы хотели бы, а не очистка всех слушателей), в то время как в первом решении вы можете только очистите их все одновременно, если вы не хотите эмулировать первую функциональность.

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

Вики Mozilla также перечисляет преимущества первого решения для любого элемента DOM, а не только для элементов HTML, и в том, что оно позволяет более детально контролировать фазу, когда слушатель активируется (захват или всплывание) с помощью третьего аргумента.

Я бы использовал оба кода, как это

function addEvent(html_element, event_name, event_function) {
    if (html_element.addEventListener) { // Modern
        html_element.addEventListener(event_name, event_function, false);
    } else if (html_element.attachEvent) { // Internet Explorer
        html_element.attachEvent("on" + event_name, event_function);
    } else { // others
        html_element["on" + event_name] = event_function;
    }
};
Другие вопросы по тегам