Допустим, у меня есть веб-приложение, в котором есть страница, которая может содержать 4 блока сценариев - сценарий, который я пишу, может быть найден в одном из этих блоков, но я не знаю, какой из них обрабатывается контроллером.
Я связываю некоторые onclick
события с кнопкой, но обнаруживаю, что они иногда выполняются в порядке, которого я не ожидал.
Есть ли способ обеспечить порядок или как вы решали эту проблему в прошлом?
javascript
jquery
events
mkoryak
источник
источник
Ответы:
Я годами пытался обобщить этот процесс, но в моем случае меня интересовал только порядок первого слушателя событий в цепочке.
Если он полезен, вот мой плагин jQuery, который связывает прослушиватель событий, который всегда запускается раньше других:
** ОБНОВЛЕНО в соответствии с изменениями jQuery (спасибо Toskan) **
Что следует отметить:
источник
this.data("events")
, см. здесь stackoverflow.com/questions/12214654/…Если порядок важен, вы можете создавать свои собственные события и привязывать обратные вызовы к срабатыванию, когда эти события запускаются другими обратными вызовами.
Нечто подобное по крайней мере.
источник
Метод Доуски хорош, если все ваши обратные вызовы всегда будут присутствовать, и вы довольны тем, что они зависят друг от друга.
Однако если вы хотите, чтобы обратные вызовы были независимы друг от друга, вы можете воспользоваться всплывающими подсказками и прикрепить последующие события в качестве делегатов к родительским элементам. Обработчики родительских элементов будут запускаться после обработчиков элемента, продолжаясь вплоть до документа. Это очень хорошо, поскольку вы можете использовать
event.stopPropagation()
иevent.preventDefault()
т. Д., Чтобы пропустить обработчики и отменить или отменить действие.Или, если вам это не нравится, вы можете использовать плагин Nick Leaches bindLast, чтобы событие было привязано последним: https://github.com/nickyleach/jQuery.bindLast .
Или, если вы используете jQuery 1.5, вы также можете сделать что-то умное с новым отложенным объектом.
источник
.delegate
больше не используется, и вы должны теперь использовать.on
, но я не знаю, как вы можете достичь того же поведения сon
Порядок вызова связанных обратных вызовов управляется данными событий каждого объекта jQuery. Нет никаких функций (о которых я знаю), которые бы позволяли вам просматривать и манипулировать этими данными напрямую, вы можете использовать только bind () и unbind () (или любую из эквивалентных вспомогательных функций).
Лучше всего использовать метод Доуски, вы должны модифицировать различные связанные обратные вызовы, чтобы связать их с упорядоченной последовательностью пользовательских событий, с «первым» обратным вызовом, связанным с «реальным» событием. Таким образом, независимо от того, в каком порядке они связаны, последовательность будет выполняться правильно.
Единственная альтернатива, которую я вижу, это то, что вы действительно, действительно, не хотите обдумывать: если вы знаете, что синтаксис привязки функций, возможно, был связан до вас, попытайтесь отменить привязку всех этих функций, а затем повторно связать их в правильном порядке самостоятельно. Это просто напрашивается на неприятности, потому что теперь у вас есть дублированный код.
Было бы здорово, если бы jQuery позволял вам просто изменять порядок связанных событий в данных событий объекта, но без написания некоторого кода для подключения к ядру jQuery, что не представляется возможным. И, вероятно, есть последствия того, что я это не подумал, поэтому, возможно, это намеренное упущение.
источник
Обратите внимание, что во вселенной jQuery это должно быть реализовано по-другому, начиная с версии 1.8. Следующая заметка о выпуске взята из блога jQuery:
У нас есть полный контроль над порядком выполнения обработчиков во вселенной jQuery . Рику указывает на это выше. Не похоже, что его ответ принес ему много любви, но эта техника очень удобна. Рассмотрим, например, всякий раз, когда вам нужно выполнить свой собственный обработчик до какого-либо обработчика в виджете библиотеки, или у вас должна быть возможность условно отменить вызов обработчика виджета:
источник
источник
просто связать обработчик нормально и затем запустить:
так например:
источник
$._data(element, 'events')[name].reverse()
работаетВы можете попробовать что-то вроде этого:
источник
У меня такая же проблема и нашел эту тему. Приведенные выше ответы могут решить эту проблему, но я не думаю, что это хорошие планы.
давайте подумаем о реальном мире.
если мы используем эти ответы, мы должны изменить наш код. Вы должны изменить свой стиль кода. что-то вроде этого:
оригинал:
взломать:
со временем подумай о своем проекте. код ужасен и труден для чтения! Другая причина проста, всегда лучше. если у вас есть 10 bindAtTheStart, возможно, нет ошибок. если у вас есть 100 bindAtTheStart, действительно ли вы уверены, что можете держать их в правильном порядке?
поэтому, если вам нужно связать несколько событий одинаково. Я думаю, что лучший способ - это управлять порядком загрузки js-файла или js-кода. JQuery может обрабатывать данные события как очередь. заказ первым пришел, первым вышел. вам не нужно менять код. просто измените порядок загрузки.
источник
Вот мой пример, охватывающий различные версии jQuery:
источник
В некоторых особых случаях, когда вы не можете изменить то, как связаны события клика (привязки событий сделаны из чужих кодов), и вы можете изменить элемент HTML, вот возможное решение ( предупреждение : это не рекомендуемый способ связывания события, другие разработчики могут убить вас за это):
При таком способе привязки ваш обработчик событий будет добавлен первым, поэтому он будет выполнен первым.
источник
JQuery 1.5 вводит обещания, и вот самая простая реализация, которую я видел, для контроля порядка выполнения. Полная документация на http://api.jquery.com/jquery.when/
источник