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

时间:2012-01-30 16:32:33

标签: jquery jquery-mobile

所以我使用Jquery mobile取得了巨大的成功,除了一个问题。 现在每当用户导航动态内容页面时,无论显示什么内容,底部总会有一个按钮,当点击时,将内容通过电子邮件发送到指定的地址;效果很好。 现在,第一次加载页面时,单击会触发一次事件。在第二次访问时,它被解雇了两次,第三次等等,你得到了重点。我已经在网上搜索并实现了我可能遇到的每一个修复,例如使用“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 个答案:

答案 0 :(得分:13)

从jQuery 1.7开始,不推荐使用.live()方法。使用.on()附加事件处理程序。

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

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

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

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

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

$(document).undelegate('.eb', 'click').delegate('.eb', 'click', function() {
 // ...
});

答案 1 :(得分: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;
    }); 

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

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

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

您会注意到我的两个示例都为.live()更改.delegate(),因为它的执行速度稍快,即使从document元素委派也是如此。 .delegate()的真正优势在于您可以选择根元素而不必绑定到document元素:http://api.jquery.com/delegate

答案 2 :(得分:2)

我通过意识到div本身问题#page来解决这个问题。 这个页面加载了动态内容,但是id从未这样做过,因此它在某个地方缓存了某个地方,并且在每次新访问时逐渐被激活。 我刚刚添加了一些PHP代码,以便在每个页面加载时创建一个唯一的div id。

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

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

答案 3 :(得分:0)

如果您怀疑某个表单(例如弹出窗体)在您提交尝试添加数据时正在创建多个页面-ajax =&#34; false&#34;到每个表单的表单元素。这解决了我的问题。