как правильно отвязать события в Jquery-Mobile, используя включение/выключение, когда страница хранится в DOM?

Поскольку Jquery Mobile сохраняет некоторые страницы в DOM при навигации, страницу можно посетить несколько раз при переходе туда и обратно.

Если я привязываюсь к странице, как показано ниже, и внутри этой привязки выполняю всю логику моей страницы, которая включает «привязки вложенных элементов»:

// listener for the page to show:
$(document).on('pagebeforeshow.register', '#register', function() {

    // stuff

    // page event bindings:
    $(document).on('click.register', '.registerSubmitter', function(e) {
        // do something
        });
    });

Переход туда и обратно приводит к тому, что моя вложенная привязка присоединяется несколько раз.

Прямо сейчас пытаюсь обойти это так (не работает...):

 $(document).on('click', '.registrySubmitter', function(e) {

         if ( $(this).attr('val') != true ) {
            $(this).attr('val') == true;
            // do something
            }
     });

Поэтому я разрешаю только первую привязку, а затем блокирую все последующие попытки привязки.

Хотя это работает, это далеко не оптимально.

Вопрос:
Как и когда привязки событий должны быть правильно развязаны/отключены? Есть ли общий способ (убить всех) или мне нужно делать эту привязку для каждой привязки? Возможно, что более важно: с точки зрения производительности лучше сделать привязку один раз и сохранить ее или привязать/отменить привязку, когда пользователь заходит на страницу или покидает ее?

Спасибо за отзыв!

EDIT:
Итак, я создаю пространство имен для всех своих событий, а затем слушаю pageHide следующим образом:

$(document).on('pagehide.register', '#register', function(){
   $(document).off('.registryEvents');
   });

Хотя это, кажется, отменяет привязку, оно также срабатывает, когда я закрываю пользовательский диалог/меню выбора на странице, поэтому я теряю свои привязки, прежде чем покинуть страницу. Итак, частичный ответ, я должен использовать off(), но как привязать страницу к действительно оставленной странице по сравнению с открытием и закрытием меню выбора?


person frequent    schedule 08.06.2012    source источник


Ответы (1)


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

У меня есть два предложения:

  • Используйте событие pageinit или pagecreate, чтобы запускать привязки для конкретных страниц только тогда, когда страницы добавляются в DOM и инициализируются. Используя этот метод, я бы не делегировал привязки событий в обработчиках событий pageinit или pagecreate, потому что, когда они срабатывают, все элементы на псевдостранице находятся в DOM:

.

$(document).on('pageinit', '#register', function() {
    //note that `this` refers to the `#register` element
    $(this).find('.registerSubmitter').on('click', function(e) {
        // do something
    });
});
  • Привяжите делегированные обработчики событий один раз и не беспокойтесь о том, когда страницы действительно находятся в DOM:

.

//this can be run in the global scope
$(document).on('click.register', '.registerSubmitter', function(e) {
    // do something
});

По сути, когда вы привязываете событие, используя делегирование, как и вы, фактическая нагрузка на ЦП при добавлении обработчика событий меньше, но каждый раз, когда отправляется событие (любого рода, которое всплывает), его необходимо проверять, соответствует ли оно селектору делегированного обработчика событий. .

При прямой привязке к элементам обычно требуется больше времени для фактической привязки, потому что каждый отдельный элемент должен быть привязан к, а не привязываться один раз к элементу document, как при делегировании события. Однако это имеет то преимущество, что код не запускается, если определенный элемент не получает определенное событие.

Краткий обзор документации:

Запускается на инициализируемой странице после инициализации. Мы рекомендуем привязку к этому событию вместо DOM ready(), потому что это будет работать независимо от того, загружается ли страница напрямую или содержимое перетаскивается на другую страницу как часть системы навигации Ajax.

Источник: http://jquerymobile.com/demos/1.1.0/docs/api/events.html

person Jasper    schedule 08.06.2012
comment
Я думал, что pageinit запускается только один раз при инициализации приложения. Запускается ли он при добавлении каждой новой страницы? - person frequent; 08.06.2012
comment
Да, он будет запускаться каждый раз при инициализации псевдостраницы. - person Jasper; 08.06.2012
comment
Я использовал ваше второе предложение внутри pagebeforeshow, которое при переходе назад и вперед на страницу регистрации вызывало множественные привязки. Так что я должен просто сделать это в глобальном масштабе и все? Звучит легко... - person frequent; 08.06.2012
comment
Если вы используете делегирование событий, сделайте это один раз, не помещайте привязку делегированного события внутрь другой привязки делегированного события, потому что каждый раз, когда вы добавляете обработчик события к элементу document, они просто складываются. Поэтому я предлагаю либо поместить делегированные привязки событий вне любых других обработчиков событий, либо сделать внутренние обработчики событий обычными привязками стиля .bind(), чтобы они не сохранялись после удаления псевдостраницы из DOM (мне нравится этот метод ). - person Jasper; 08.06.2012
comment
это все еще сложно, так как я загружаю страницу, а затем загружаю формы в зависимости от выбора пользователя. Привязка к этим элементам формы... нужно переосмыслить это. - person frequent; 11.06.2012