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

В моем ответе на следующий вопрос SO: Что означает привязка событий?, я сделал мимолетное замечание, что использование встроенного -JavaScript/Early-Binding для привязки событий JavaScript «часто вводили в заблуждение».

Например:

<input id="MyButton" type="button" value="clickme" onlick="Somefunction()" />

Я выступал за подход «позднего связывания», при котором в разметке не упоминается JavaScript, что, как я понимаю, является установленной передовой практикой. Однако комментаторы утверждали, что были случаи, которые требовали его использования, и мне было интересно, что это может быть.

Не участвуя в обсуждении относительных достоинств того и другого, может ли кто-нибудь подумать о каких-либо обстоятельствах, которые диктуют вам использование (например) атрибута onclick вместо подхода позднего связывания.

Большое спасибо


person James Wiseman    schedule 13.06.2011    source источник
comment
Их использует Google, как и люди, которые возятся с ними. Я использую их, когда делаю букмарклеты.   -  person qwertymk    schedule 13.06.2011
comment
@qwertymk: Хотите расширить пример букмарклетов в ответе? У меня есть забавное ощущение, что это привлечет больше голосов ;-)   -  person James Wiseman    schedule 13.06.2011
comment
Когда вы управляете HTML, нет допустимого варианта использования встроенной привязки.   -  person Raynos    schedule 13.06.2011
comment
Рейнос – Я думаю, у тебя это наоборот. Зачем полагаться на сценарии на стороне клиента для добавления прослушивателей, которые могут быть добавлены на сервер более эффективно (особенно с использованием кэшированных или статических страниц), особенно когда вы управляете HTML? Также позволяет избежать проблем с загрузкой/DOMReady при динамическом добавлении — слушатели становятся доступными, как только появляется элемент.   -  person RobG    schedule 14.06.2011


Ответы (3)


Я думаю, что многие разработчики сделают это либо по незнанию, либо от незнания (что, конечно, распространено), а остальные разработчики сделают это потому, что просто удобнее использовать атрибуты HTML-JS, чем позднее связывание, если вы знаете, что определенные объекты и функции всегда загружаются на каждой странице, и они будут просто «там».

Я думаю, что это особенно верно, когда упомянутый HTML исходит из обратного вызова AJAX. Возьмем пример, когда запрос AJAX возвращается с ответом в формате HTML, и этот HTML-код вставляется на страницу. Теперь наивный разработчик будет думать примерно так:

  • Я понятия не имею, какие элементы находятся внутри этого HTML-кода ответа, поэтому я не знаю, какие поздние привязки мне нужно добавить.
  • Возможно, мне нужно добавить их все на всякий случай! Или написать какой-нибудь скрипт разбора, который обнаруживает элементы и привязывается к тем, которые я нахожу?
  • Но что, если мне нужно привязать к чему-то, чего еще не существует? Пришло время написать длинный встроенный JavaScript!

Все это можно устранить, используя своего рода вездесущую привязку, которая применяется ко всем текущим и будущим элементам на странице. В jQuery эквивалентом является live(). Вместо того, чтобы писать:

$('.foo').click(function(){...});

Вы можете написать:

$('.foo').live('click', function(){...});

Теперь все элементы с именем класса 'foo' будут выполнять функцию при нажатии, включая элементы, которые в настоящее время не существуют. Очень полезно для динамических интерфейсов AJAX.

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

person BoffinBrain    schedule 13.06.2011
comment
+1 Превосходный ответ. Да, я знал, но нет ничего лучше утверждения, что ваша реальность такова, как вы ее воспринимаете :-) - person James Wiseman; 13.06.2011
comment
.live это дьявол. Используйте .delegate - person Raynos; 13.06.2011
comment
@Raynos Хорошая находка. Я знал, что у live() есть несколько проблем, но не знал, что могу сделать то же самое на более низком уровне DOM. Думаю, хорошо для производительности. - person BoffinBrain; 13.06.2011

комментаторы утверждали, что были случаи, когда требовалось его использование

Я полагаю, что я один из тех комментаторов. На самом деле я сказал, что встроенные слушатели «являются разумным вариантом при определенных обстоятельствах». Я не думаю, что есть случаи, когда это «необходимо» (что я понимаю в этом контексте как необходимое).

Добавление встроенных слушателей — это просто применение той же логики на сервере для добавления слушателей, что и на клиенте, и имеет следующие преимущества:

  1. Разметку можно создавать и кэшировать или использовать как статические страницы, слушатели не добавляются каждым клиентом снова и снова при загрузке страниц.
  2. Полностью удалены проблемы, связанные с задержкой между доступностью элемента и добавлением слушателя функциями DOMReady или onload или «нижними скриптами».
  3. Капризы различных «кроссбраузерных» функций DOMReady с откатом при загрузке удалены — у таких функций нет возможности не добавить слушателей, если они не используются.

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

Если вы считаете, что «раннее связывание» слушателей — это хорошо, то сделайте это как можно раньше — поместите их в строку. :-)

PS. Я также думаю, что сказал, что мне не нравится использование «привязки» в этом контексте, поскольку слушатели не привязаны к элементам в каком-либо реальном смысле. Это просто функции, которые вызываются, когда элемент получает связанное событие. Единственный тип привязки заключается в том, что ключевое слово this слушателя может быть установлено для ссылки на связанный элемент (что одинаково во всех браузерах для встроенных слушателей, но не обязательно для тех, которые добавляются позже).

person RobG    schedule 14.06.2011
comment
1. Разметка может быть создана и кэширована или использована как статические страницы, прослушиватели не добавляются каждым клиентом снова и снова, когда страницы загружаются. Файлы JavaScript, которые присоединяют прослушиватели, кэшируются. Слушатели добавляются каждым клиентом снова и снова. Это происходит, когда браузер анализирует DOM и подключает слушателей для вас. - person Raynos; 14.06.2011
comment
2. Полностью устранены проблемы, связанные с задержкой между доступностью элемента и добавлением слушателя функциями DOMReady или onload или нижними скриптами. Задержка должна быть небольшой. Клиентов не следует поощрять к взаимодействию со страницей до того, как она завершит загрузку, так как это требует от вас значительно более надежного кода и защиты от ошибок частично загруженного состояния. Если задержка заметна, значит, вы неправильно выполняете загрузку, то есть недостаточно кеширования/ленивой загрузки. - person Raynos; 14.06.2011
comment
3 Удалены капризы различных кросс-браузерных функций DOMReady с откатом при загрузке — у таких функций нет возможности не добавить слушателей, если они не используются. Если конкретный разработчик не использует служебную библиотеку DOMReady, то он стреляет в себя нога без причины. domReady занимает всего 0,5 КБ. Нет причин не использовать его. - person Raynos; 14.06.2011
comment
+1 за веские аргументы в пользу использования встроенных событий! - person Raynos; 14.06.2011
comment
+1 От меня тоже. Именно такого рода обсуждения мне нравятся SO. - person James Wiseman; 14.06.2011
comment
Джеймс - SO активно препятствует обсуждению своей политики и структуры публикации. Вот почему это обсуждение было продолжено в отдельном вопросе. Большинство тем для обсуждения закрываются очень быстро. - person RobG; 15.06.2011
comment
Raynos - что касается № 2, вы не можете контролировать скорость загрузки или отображения страниц, кроме размера. Сетевая задержка между сервером и клиентом в большинстве случаев совершенно неизвестна и может сильно различаться между последовательными запросами от одного и того же клиента, особенно если задействована мобильная сеть или устройство. Пользователям не нужно ждать, пока загрузится вся страница, прежде чем они смогут работать с ней. - person RobG; 15.06.2011

Причины, по которым атрибуты onclick плохие:

onclick="foo()"

  • Вы передаете строку кода, которая оценивается во время выполнения при щелчке элемента. Это неэффективно и использует ужасы eval
  • Вы вынуждены хранить функцию foo в глобальной области, тем самым загрязняя глобальную область всей логикой обработки событий.
person Raynos    schedule 14.06.2011
comment
Код не оценивается во время выполнения, он анализируется по мере загрузки страницы и вызывается обработчиком (точно так же, как динамически добавляемые слушатели), в большинстве случаев это вызов одной функции. Ужасы eval не имеют значения (и сильно преувеличены). Разговоры о загрязнении глобальной области видимости дополнительными свойствами — это нагнетание паники, единственная проблема — конфликты имен, которых легко избежать. - person RobG; 15.06.2011