Как вы изменяете порядок запуска событий того же события? - PullRequest
5 голосов
/ 16 февраля 2012

Jquery bind удивителен, но я не знаю, в каком порядке происходит связывание.Моя текущая проблема такова:

$(document.body).delegate('form', methods.checkForm);
$('form').bind('submit', methods.submitFormIfCheckedFormIsTrue);

methods.checkForm = function (e) {
    if (!$(this).isVerified()) {
        return false;
    }
    return true;
};
methods.submitFormIfCheckedFormIsTrue = function (e) {
    e.preventDefault();
    $.ajax("/submitForm", {
        data:$(this).serialize(),
        type:"post"
    });
};

Это, очевидно, не тот код, который я использую, но он довольно близок.Что происходит, так это то, что функция submitFormIfCheckedFormIsTrue запускается до или во время функции checkForm, поэтому проверка довольно бесполезна.Я взломал его, добавив в форму класс «флажок», и проверил, есть ли у формы этот класс в другой функции ... но затем вы нажимаете «Отправить», он проверяет, а затем вы должны нажать его еще раз, чтобы отправитьесли все пошло правильно ... что отстает.

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

Главное, что я хочу знать ... как изменить порядок или каким-то образом установить приоритет событий ...

Ответы [ 2 ]

3 голосов
/ 16 февраля 2012

Если вы используете «делегировать» так, как это делается в вашем примере, тогда отправка ajax всегда будет выполняться в первую очередь, поэтому краткий ответ на ваш вопрос «Вы не можете».Ваш делегат присоединен к элементу body, поэтому события, прикрепленные к элементам ближе к форме в дереве DOM, будут запускаться первыми.

События всплывают из формы -> body, поэтому при упорядочении

Один из вариантов - ваша проверка запускает второе событие.

methods.checkForm = function (e) {
  e.preventDefault()

  if ($(this).isVerified()) {
    $(this).trigger('form-verified');
  }
};

Затем вместо привязки другого обработчика к 'submit', вы привязываете его к 'form-verified'.

$('form').bind('form-verified', methods.submitFormIfCheckedFormIsTrue);

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

Кроме того, если вы используете jQuery> = 1,7, тогда вы должны использовать on вместо bind и delegate.http://api.jquery.com/on/

Обновление

Если оба связаны с одним и тем же элементом, они будут сработать в том порядке, в котором они были присоединены к элементу.Предполагая, что checkForm привязан перед другим, проблема в том, что return false; не останавливает запуск других событий, если они присоединены к тому же элементу.Для этого вам также понадобится e.stopImmediatePropagation().

methods.checkForm = function (e) {
  e.preventDefault()

  if (!$(this).isVerified()) {
    e.stopImmediatePropagation();
  }
};

Здесь также есть полезный ответ, если вам когда-нибудь придется изменить порядок событий. Обработчики событий jQuery всегда выполняются в том порядке, в котором они были связаны - каким-либо образом это обходится?

0 голосов
/ 16 февраля 2012

В общем смысле обработчики событий будут вызываться в том порядке, в котором они были связаны, но только если они связаны на одном уровне.В вашем случае вы связываете одно непосредственно с формой, в то время как другое является делегированным обработчиком, связанным на уровне document.body.Сначала будет происходить прямое связывание, а затем событие всплывает, чтобы быть обработанным другим.

Если вы связываете оба обработчика на одном уровне с .delegate(), тогда они должны вызываться по порядку:

$(document.body).delegate('form', 'submit', methods.checkForm);
$(document.body).delegate('form', 'submit',
                                  methods.submitFormIfCheckedFormIsTrue); 

Затем в первом (универсальном) обработчике вы должны вызвать метод event.stopImmediatePropagation() , чтобы предотвратить вызов других обработчиков (отметив, что простой возврат false предотвращает использование значения по умолчанию и останавливает дальнейшее всплытие события), но это не останавливает выполнение других обработчиков на этом уровне):

methods.checkForm = function (e) {
  if (!$(this).isVerified()) {
      e.stopImmediatePropagation();
      return false;
  }
  return true;
};  

(Кстати, код, показанный в вопросе, исключил событие (второй параметр) из вызова .delegate()- Я вставил это в свой код.)

Или связать оба обработчика напрямую, вместо использования .delegate().Говоря об использовании .delegate(), если вы используете последнюю версию jQuery, вы можете переключиться на использование .on(), нового метода привязки событий для всего.

"Чтослучается, функция submitFormIfCheckedFormIsTrue запускается до или во время функции checkForm "

Определенно до, а не во время.(Практически во всех браузерах) JavaScript работает в одном потоке, поэтому у вас никогда не будет одновременно работать две функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...