Один большой аргумент против встроенных обработчиков событий, и аргумент, который рассматривается другими ответами здесь, это разделение представления и логики .
Однако на самом деле существует более серьезная проблема. ИМО: каким-то неуловимым способом оценки встроенных обработчиков событий.
Как вы, возможно, знаете, содержимое атрибутов on*
будет использоваться как body функции-обработчика событий. Но какими характеристиками обладает эта функция?
Одним из удивительных является то, что свойства некоторых элементов-предков и самого элемента находятся в scope встроенного обработчика событий.
<form>
<input name="foo" />
<button type="button" onclick="console.log(foo); console.log(window.foo);">
Click me
</button>
<div onclick="console.log(foo);">Click me as well!</div>
</form>
Нажатие button
журналов
<input name="foo"></input>
undefined
в консоли. Тот факт, что window.foo
равен undefined
, говорит о том, что глобальной переменной foo
нет. Так откуда берется переменная foo
? Почему console.log(foo)
регистрирует элемент ввода и не выдает ошибку ссылки?
Поскольку свойства элемента form
находятся в области действия обработчика событий, а элемент form
имеет свойство для каждого именованного элемента управления формы, который он содержит. Вы можете легко проверить это с помощью console.log(document.querySelector('form').foo)
.
Теперь, щелкнув элемент div
, выдается ошибка ссылки:
ReferenceError: foo is not defined
Таким образом, очевидно, что элемент form
находится только в области элементов управления формой, а не какой-либо потомок. Насколько это сбивает с толку?
Аналогично, свойства объекта document
также находятся в области действия встроенных обработчиков событий, что может привести к некоторым неожиданным ошибкам (знаете ли вы, что document
имеет свойство plugins
?).
Как именно оцениваются встроенные обработчики событий, формализовано в спецификации HTML5 . Создайте цикл на шаге 10, в частности, где описано создание цепочки областей действия.
Заключение
Из-за неявного неявного соединения между элементами и встроенными обработчиками событий ошибки могут быть действительно сложными для отслеживания. Конечно, хорошо использовать встроенные обработчики событий, если вы просто хотите что-то протестировать. Но использование их в производственном коде сопряжено с более высокими затратами на обслуживание.
Статьи на quirksmode.org очень хорошо объясняют различные способы привязки обработчиков событий и их (dis) преимущества.