Оба являются правильными, но ни один из них не является «лучшим» как таковым, и может быть причина, по которой разработчик решил использовать оба подхода.
Прослушиватели событий (addEventListener и IE attachEvent)
В более ранних версиях Internet Explorer JavaScript реализован не так, как в большинстве других браузеров.В версиях менее 9 вы используете метод attachEvent
[ doc ], например:
element.attachEvent('onclick', function() { /* do stuff here*/ });
В большинстве других браузеров (включая IE 9 и выше) вы используете addEventListener
[ doc ], например:
element.addEventListener('click', function() { /* do stuff here*/ }, false);
Используя этот подход ( события DOM уровня 2 ), вы можете прикрепить теоретически неограниченное количество событий клюбой отдельный элемент.Единственным практическим ограничением является память на стороне клиента и другие проблемы производительности, которые различны для каждого браузера.
Приведенные выше примеры представляют использование анонимной функции [ doc ].Вы также можете добавить прослушиватель событий, используя ссылку на функцию [ doc ] или замыкание [ doc ]:
var myFunctionReference = function() { /* do stuff here*/ }
element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);
Другая важная функция addEventListener
- этопоследний параметр, который управляет реакцией слушателя на всплывающие события [ doc ].Я передавал false в примерах, что является стандартным для, вероятно, 95% случаев использования.Не существует эквивалентного аргумента для attachEvent
или при использовании встроенных событий.
Встроенные события (свойство HTML onclick = "" и element.onclick)
Во всехВ браузерах, поддерживающих javascript, вы можете поместить прослушиватель событий встроенным, то есть прямо в HTML-код.Вы, наверное, видели это:
<a id="testing" href="#" onclick="alert('did stuff inline');">Click me</a>
Большинство опытных разработчиков избегают этого метода, но он выполняет свою работу;это просто и прямо.Вы не можете использовать здесь замыкания или анонимные функции (хотя сам обработчик является своего рода анонимной функцией), и ваш контроль над областью ограничен.
Другой упомянутый вами метод:
element.onclick = function () { /*do stuff here */ };
... является эквивалентом встроенного JavaScript, за исключением того, что вы имеете больший контроль над областью (поскольку вы пишете сценарий, а не HTML) и можете использовать анонимные функции, ссылки на функции и / или замыкания.
Существенным недостатком встроенных событий является то, что в отличие от прослушивателей событий, описанных выше, вам может быть назначено только одно встроенное событие.Встроенные события сохраняются как атрибут / свойство элемента [ doc ], что означает, что его можно перезаписать.
Используя пример <a>
из приведенного выше HTML-кода:
var element = document.getElementById('testing');
element.onclick = function () { alert('did stuff #1'); };
element.onclick = function () { alert('did stuff #2'); };
... когда вы щелкаете элемент, вы только видите «Сделал материал №2» - вы перезаписали первое назначенное свойство onclick
вторым значением, и выперезаписал оригинальное встроенное свойство HTML onclick
.Проверьте это здесь: http://jsfiddle.net/jpgah/.
Вообще говоря, не использовать встроенные события .Для этого могут быть конкретные варианты использования, но если вы не уверены на 100%, что у вас есть этот вариант использования, то вы не должны и не должны использовать встроенные события.
Modern Javascript (Angular и т. П.)
С тех пор как этот ответ был первоначально опубликован, фреймворки javascript, такие как Angular, стали гораздо более популярными.Такой код вы увидите в шаблоне Angular:
<button (click)="doSomething()">Do Something</button>
Это выглядит как встроенное событие, но это не так.Этот тип шаблона будет транслироваться в более сложный код, который использует прослушиватели событий за кулисами.Все, что я написал о событиях здесь, по-прежнему применимо, но вы избавлены от мельчайших частиц хотя бы одним слоем.Вы должны понимать основные моменты, но если ваши лучшие практики современной JS-фреймворка предполагают написание такого рода кода в шаблоне, не думайте, что вы используете встроенное событие - это не так.
Что лучше?
Вопрос в совместимости и необходимости браузера.Вам в настоящее время нужно прикрепить более одного события к элементу?Будете ли вы в будущем?Скорее всего, вы будете.attachEvent и addEventListener необходимы.Если нет, встроенное событие может показаться, что они справятся с задачей, но вам гораздо лучше подготовиться к будущему, которое, хотя и может показаться маловероятным, по крайней мере, предсказуемо.Есть шанс, что вам придется перейти к слушателям событий на основе JS, так что вы можете просто начать там.Не используйте встроенные события.
jQuery и другие платформы javascript инкапсулируют различные реализации браузером событий DOM уровня 2 в общих моделях, поэтому вы можете писать кросс-браузерный совместимый код, не беспокоясь об истории IE как мятежника,Тот же код с jQuery, все кросс-браузерные и готовые к работе:
$(element).on('click', function () { /* do stuff */ });
Не исчерпайте себя и получите фреймворк только для этого.Вы можете легко запустить свою собственную маленькую утилиту, чтобы позаботиться о старых браузерах:
function addEvent(element, evnt, funct){
if (element.attachEvent)
return element.attachEvent('on'+evnt, funct);
else
return element.addEventListener(evnt, funct, false);
}
// example
addEvent(
document.getElementById('myElement'),
'click',
function () { alert('hi!'); }
);
Попробуйте: http://jsfiddle.net/bmArj/
Принимая все это во внимание, если только вы не используете скриптПри взгляде на различия в браузере учитывались иным образом (в коде, не показанном в вашем вопросе), часть, использующая addEventListener
, не будет работать в версиях IE менее 9.
Документация и сопутствующее чтение