Jquery mobile .click在新页面访问时多次触发

Nat*_*ade 9 jquery jquery-mobile

所以我使用Jquery mobile取得了巨大的成功,除了一个问题.现在每当用户导航动态内容页面时,无论显示什么内容,底部总会有一个按钮,当点击时,将内容通过电子邮件发送到指定的地址; 效果很好.现在,第一次加载页面时,单击会触发一次事件.在第二次访问时,它被解雇了两次,第三次等等,你得到了重点.我已经冲刷净,并落实每一个解决我能遇到,如使用"pagecreate",而不是"pageinit",绑定,解除绑定,除去股利,在DOM关闭缓存但没有任何工程.我唯一的成功是使用.one()点击,但如果再次点击则需要触发.这是结构.我必须.js使用这个加载每个文件来开始

$( "#page" ).live( "pageinit", function() { 
Run Code Online (Sandbox Code Playgroud)

现在我将电子邮件功能和其他内容放在一个文件中,但它更容易将它们分开,我听说它并不重要.现在,这是在中调用的电子邮件功能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;
    }); 
Run Code Online (Sandbox Code Playgroud)

除了.click每个新页面上的增量触发外,一切都完美无瑕.谁能引导我朝着正确的方向前进?

Ing*_*mar 13

从jQuery 1.7开始,该.live()方法已被弃用.使用.on()附加的事件处理程序.

如果您使用的是1.7+,请先尝试取消绑定点击事件.off().

$('.eb').off('click').on('click', function() {
 // ...
}); 
Run Code Online (Sandbox Code Playgroud)

如果你必须使用.live()你可以取消绑定事件.die()

$('.eb').die('click').live('click', function() {
 // ...
});
Run Code Online (Sandbox Code Playgroud)

或者更好地使用.delegate().undelegate()取消父元素:

$(document).undelegate('.eb', 'click').delegate('.eb', 'click', function() {
 // ...
});
Run Code Online (Sandbox Code Playgroud)


Jas*_*per 10

只需将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;
    }); 
Run Code Online (Sandbox Code Playgroud)

当您使用事件委托时,您不希望在另一个事件处理程序中绑定,因为每次该事件处理程序触发时您将重新绑定(并且当您委派事件处理程序时,它们将被委派给DOM的生命周期).

您也可以使用.bind()而不是.live()(这是我的首选方法):

$( document ).delegate( "#page", "pageinit", function() {
    $('.eb').bind('click', ...);
});
Run Code Online (Sandbox Code Playgroud)

您会注意到我的两个示例都更改了.live(),.delegate()因为它甚至在从document元素委派时执行得稍快一些..delegate()真正的优势在于您可以选择根元素而不必绑定到document元素:http://api.jquery.com/delegate


Nat*_*ade 2

我通过意识到问题出在 div 本身来解决这个问题#page。该页面加载了动态内容,但 id 从未加载过,因此它会在某处缓存,并在每次新访问时增量触发。我刚刚添加了一些 PHP 代码来在每个页面加载时创建一个唯一的 div id。

<?php $id = uniqid() ?>
<div id="<?php echo $id; ?>">CONTENT</div>
Run Code Online (Sandbox Code Playgroud)

这解决了问题,无论页面重新加载多少次,它都只会触发一次。

  • 此过程留下了各种不必要的事件绑定(用户越深入站点,执行速度就越慢,因为您只是加载越来越多的委派事件处理程序,每当事件冒泡时都必须检查这些处理程序)上 DOM)。您的问题是处理动态内容的常见陷阱,您对事件绑定过于自由。真正的解决方法是在不需要的地方停止使用委托事件处理程序。我很高兴你想出了一些办法,但这不是一个好的答案。 (4认同)