Jquery mobile .click несколько раз выстреливает при посещении новой страницы - PullRequest
9 голосов
/ 30 января 2012

Так что я использую Jquery Mobile с большим успехом, за исключением одного выпуска.Теперь каждый раз, когда пользователь перемещается по странице динамического контента, независимо от того, какой контент отображается, всегда есть кнопка внизу, которая при нажатии отправляет контент по электронной почте на указанный адрес;работает отлично.Теперь при первой загрузке страницы щелчок запускает событие один раз.При втором посещении его стреляют дважды, третьем - 3 раза и т. Д., Вы получаете очко.Я проверил сеть и внедрил все исправления, с которыми я мог столкнуться, например, используя «pagecreate» вместо «pageinit», привязку, отмену привязки, удаление div, отключение кэширования в DOM, но ничего не работает.Единственный успех, который у меня был, - это использование .one() на клике, но при повторном нажатии его нужно запустить.Вот структура.У меня есть .js файлы, которые загружаются каждый с этим, чтобы начать

$( "#page" ).live( "pageinit", function() { 

Теперь у меня была функция электронной почты и другие вещи в одном файле, но это облегчает их разделение, и я слышал, что это не такиметь значение.Теперь вот функция электронной почты, вызываемая в pageinit

$('.eb').live('click', function() {
        var id = $('.eb').attr('id');
        var to = $('#recipient').val();
        var message = $('#email').html();

        var atpos = to.indexOf("@");
        var dotpos = to.lastIndexOf(".");
        if (atpos < 1 || dotpos < atpos + 2 || dotpos + 2 >= to.length) {
            alert('Please enter a valid email address!');
            return false;
        } 

        if(to.length == 0) {
            alert('Please enter a valid email address!');
            return false;
        } 

        $.mobile.showPageLoadingMsg();

        $.post('./services/service.email.php', { id: id, to: to, message: message}, function(data) {
            if(data.success == true) {
                $.mobile.hidePageLoadingMsg();
                alert('Your recipe has been sent!');
                $('#recipient').val('');
                return true;
            } 

            if(data.success == false) {
                if(data.fail == 1) {
                    alert('An error has occured sending your recipe. Try again soon!');
                    return false;
                }

                if(data.fail == 2) {
                    alert('Please enter a valid email address!');
                }
            }
        }, 'json');
            return false;
    }); 

Все работает безупречно, за исключением пошагового запуска .click на каждой новой странице.Кто-нибудь может привести меня в правильном направлении?

Ответы [ 4 ]

13 голосов
/ 30 января 2012

Начиная с jQuery 1.7, метод .live() устарел.Используйте .on() для присоединения обработчиков событий.

Если вы используете 1.7+, попробуйте отменить привязку события click, сначала набрав .off().

$('.eb').off('click').on('click', function() {
 // ...
}); 

, если вам нужно использовать .live()Вы можете отменить привязку событий с помощью .die()

$('.eb').die('click').live('click', function() {
 // ...
});

или лучше использовать .delegate() и .undelegate() un родительский элемент:

$(document).undelegate('.eb', 'click').delegate('.eb', 'click', function() {
 // ...
});
10 голосов
/ 30 января 2012

Просто переместите код обработчика событий click за пределы кода обработчика событий pageinit, например:

$( document ).delegate( "#page", "pageinit", function() {


});
$(document).delegate('.eb', 'click', function() {
        var id = $('.eb').attr('id');
        var to = $('#recipient').val();
        var message = $('#email').html();

        var atpos = to.indexOf("@");
        var dotpos = to.lastIndexOf(".");
        if (atpos < 1 || dotpos < atpos + 2 || dotpos + 2 >= to.length) {
            alert('Please enter a valid email address!');
            return false;
        } 

        if(to.length == 0) {
            alert('Please enter a valid email address!');
            return false;
        } 

        $.mobile.showPageLoadingMsg();

        $.post('./services/service.email.php', { id: id, to: to, message: message}, function(data) {
            if(data.success == true) {
                $.mobile.hidePageLoadingMsg();
                alert('Your recipe has been sent!');
                $('#recipient').val('');
                return true;
            } 

            if(data.success == false) {
                if(data.fail == 1) {
                    alert('An error has occured sending your recipe. Try again soon!');
                    return false;
                }

                if(data.fail == 2) {
                    alert('Please enter a valid email address!');
                }
            }
        }, 'json');
            return false;
    }); 

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

Вы также можете использовать .bind() вместо .live() (это мой предпочтительный метод):

$( document ).delegate( "#page", "pageinit", function() {
    $('.eb').bind('click', ...);
});

Вы заметите, что оба моих примера заменяют .live() на .delegate(), поскольку он работает немного быстрее даже при делегировании от элемента document.Реальная сила .delegate() в том, что вы можете выбрать корневой элемент вместо того, чтобы связываться с элементом document: http://api.jquery.com/delegate

2 голосов
/ 07 февраля 2012

Я решил это, поняв, что проблема была с самим div, #page. Эта страница была загружена динамическим контентом, но идентификатор никогда не появлялся, поэтому где-то вдоль строки она где-то кешировалась и постепенно генерировалась при каждом новом посещении. Я просто добавил немного кода PHP для создания уникального идентификатора div при каждой загрузке страницы.

<?php $id = uniqid() ?>
<div id="<?php echo $id; ?>">CONTENT</div>

Это решило проблему и сработало только один раз, независимо от того, как может произойти перезагрузка страницы.

0 голосов
/ 29 апреля 2014

Если вы подозреваете, что форма (например, всплывающая форма) создает несколько страниц при отправке, попробуйте добавить data-ajax = "false" к элементу формы каждой формы. Это решило мою проблему.

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