Встроенные слушатели не имеют никаких преимуществ, напротив, это очень несовершенный способ добавления слушателей событий к элементам HTML.
Различия в исполнении
# 1 this
значение внутри кода атрибута привязано к элементу с JavaScript with
. Во встроенном коде функция (или любая глобальная переменная) сначала ищется из элемента. Если он не найден (что обычно бывает), встроенный слушатель ищет функцию у предков элемента. Если подходящее имя свойства не найдено, поиск достигает window
и запускает глобальную функцию, которая была вызвана. Но если имя функции конфликтует с любым именем свойства в пути поиска, возникает ошибка или выполняется непредвиденная функция.
Пример того, как встроенный прослушиватель находит свойство action
формы упаковки, просто нажмите ввод:
function action () {
console.log('Not a function!?');
}
<form action="" method="post">
<input onclick="console.log(action); action();">
</form>
# 2 Возвращаемое значение кода атрибута фактически используется в определенных событиях (например, onsubmit
). Возврат false
предотвращает действие события по умолчанию. Возвращаемое значение от слушателя, прикрепленного с помощью onxxxx
или addEventListener
, всегда полностью игнорируется (для значения нет получателя).
# 3 Все переменные и функции, используемые в обработчик должен быть доступен глобально. Это тоже можно считать недостатком.
Часто неправильно понимаемое поведение
Функция, вызываемая в коде атрибута, не является фактической функцией обработчика событий, код в атрибуте сам является прикрепленным обработчиком. Следовательно, объект события и правильное значение this
присутствуют только в коде обработчика атрибута. Если вам понадобится какое-либо из этих значений в глобальной функции, вы должны передать их вручную при вызове глобальной функции.
Это нормальное поведение любого кода JavaScript, также в случае обработчик прикреплен с addEventListener
. Если вы вызовете другую функцию из обработчика событий, вы должны передать объект события и связать / передать this
значение, если этой другой функции нужны эти значения.
Пример вызова другой функции от слушателей событий.
function show () {
console.log('Called:', typeof event, this.toString());
}
const inp = document.querySelectorAll('input')[1];
inp.addEventListener('click', function (e) {
console.log('addEventListener:', typeof e, this.toString());
show();
});
<input onclick="console.log('Inline:', typeof event, this.toString()); show();" placeholder="Inline listener">
<input placeholder="addEventListener">
Как мы видим, нет никакой разницы - между типами присоединения - как обрабатываются объект события и this
значение. Когда возникает событие, во встроенном слушателе код в атрибуте - это код, выполняемый первым, тогда как для других типов присоединения первый выполняемый код является самой функцией обработчика. (Часть объекта события в примере частично не имеет значения, поскольку почти все браузеры в настоящее время реализуют глобальный объект события.)
Fl aws во встроенных слушателях
# 1 Вы можете присоединить к элементу только одного слушателя того же типа.
# 2 Встроенные слушатели являются потенциальными атакующими векторами, поскольку оба являются кодом слушателя в атрибуте, и любую функцию, вызываемую из кода атрибута, легко переопределить с помощью DevTools.
# 3 При написании встроенного прослушивателя правильно заключать строки в кавычки сложно. Сложность цитирования возрастает при написании тега Dynami c на сервере, так как вы должны позаботиться о цитировании HTML, JS и цитировании языка на стороне сервера.
# 4 Встроенные прослушиватели не работают в модулях и расширениях браузера, не принимаются многими фреймворками и не проходят никаких аудитов безопасности.
# 5 Встроенные слушатели ломают Принцип разделения проблем путем смешивания уровней представления и действий на странице.
element.onxxxx
Свойство
onxxxx
не страдает от fl aws # 3, # 4 и # 5, но вы не можете добавить более одного слушателя со свойством onxxxx
, и поскольку элементы в любом случае являются глобальными , слушатель легко переопределить с помощью DevTools.
addEventListener
В заключение: используйте addEventListener
, чтобы прикрепить события к HTML элементов, у него нет fl aws. this
правильно привязан, объект события передан правильно, можно присоединить несколько событий одного типа и без рисков для безопасности (когда обработчик не является глобально доступной функцией), потому что все происходит в инкапсулированном коде, без необходимости глобальная переменная или функция.
В качестве бонуса вы можете выбрать фазу, на которой запускается событие, без дополнительных усилий присоединить к элементам события, запускающие только один раз, и получить лучшую производительность прокрутки с определенными событиями.