为什么jQuery的点击事件会多次触发

9

我有这段示例代码 http://jsfiddle.net/DBBUL/10/

    $(document).ready(function ($) {

    $('.creategene').click(function () {

        $('#confirmCreateModal').modal();

        $('#confirmCreateYes').click(function () {
            $('#confirmCreateModal').modal('hide');

            var test = "123";
            alert(test);
            console.log(test);             
        });
    });
});

如果您点击创建按钮3次,并且每次确认时都选择“是”,则弹出警报会针对每次单击而不是仅一次单击而触发多次。
如果您点击创建按钮3次,并且每次都选择“否”,在第4次选择“是”时,警报会针对之前的每次点击而不是仅一次单击而触发。
这种行为对我来说似乎很奇怪,因为我期望警报每次单击只会触发一次。我是否需要使用.unbind()或是否有更好的解决方案?
请问有人可以告诉我为什么会发生这种情况,以及如何解决它吗?
谢谢
5个回答

18

因为您多次绑定了它。在点击事件内部嵌套点击事件意味着每次单击时,新的单击事件都将被绑定在之前已绑定的事件之上。除非单击事件创建元素,否则不要在单击事件内部绑定单击事件。也没有必要一遍又一遍地重新初始化模态框。

$(document).ready(function ($) {

    $('#confirmCreateModal').modal({show: false});

    $('#confirmCreateYes').click(function () {
        $('#confirmCreateModal').modal('hide');

        var test = "123";
        alert(test);
        console.log(test);             
    });

    $('.creategene').click(function () {

        $('#confirmCreateModal').modal('show');

    });
});

示例


如果主点击事件(.creategene)发生在knockoutjs的点击绑定中,您会如何处理?self.createGene = function () { } - iambdot
我会使用数据属性而不是JavaScript来完成这个操作,然后绑定到关闭事件。 - Kevin B
不是关闭事件,而只是“Yes”按钮。没有真正的必要初始化模态框或有一个点击事件来打开它。 - Kevin B

2
你也可以尝试这个方法 -
$("#confirmCreateYes").unbind().click(function() {
//Stuff
});

一个代码块本身并不能提供一个好的答案。请添加解释(为什么它解决了问题,哪里出错了等等...) - Louis Barranqueiro

2

将代码修改为以下内容

$(document).ready(function ($) {

    $('.creategene').click(function () {

        $('#confirmCreateModal').modal();


    });
    $('#confirmCreateYes').click(function () {
            $('#confirmCreateModal').modal('hide');

            var test = "123";
            alert(test);
            console.log(test);             
        });
});

fiddle

您不需要在每个按钮点击中绑定$('#confirmCreateYes').click

注意:请保留HTML标签。


1
将以下内容添加到您的代码中:

$( "#confirmCreateYes").unbind( "click" );

像这样:
$(document).ready(function ($) {

$('.creategene').click(function () {

    $('#confirmCreateModal').modal();

    $('#confirmCreateYes').click(function () {
        $('#confirmCreateModal').modal('hide');

        var test = "123";
        alert(test);
        console.log(test);
        $( "#confirmCreateYes").unbind( "click" );
    });
});

它将解除事件绑定,以便它不会在之前的事件上再次绑定。这允许事件仅在原始点击事件中触发。

这不是一个好方法。它将解除附加到元素的所有点击事件。我将在此处保留它以供学习目的。


这样做行不通。如果选择这种方法,解绑需要在绑定之前进行,而不是在函数实现内部进行(?). 但是,出于多种原因,这仍然是一种糟糕的方法,首先是您盲目地解除了附加到此项的所有单击事件,而不仅仅是所讨论的那一个。 - Robert Noack
1
不,将其放在 @kylealonius 放置的位置比其他任何地方都更合理。它将在尽可能早的时间解除绑定。虽然,进一步将其简化为使用 .one() 而不是 .click() 更有意义,这样您甚至不必自行解除绑定。但是,接下来你会问,为什么要解除绑定呢?它只能在模态框可见时触发。 - Kevin B
罗伯特关于解除所有点击事件的说法是正确的。我之前没有想到过这一点。我试图保留原始设计。但由于创建“是”按钮具有ID,其他方法更好,因为点击事件不会对任何其他元素触发。 - kylealonius

0

目前这是对我有效的代码:

$("#parentID").off("click", ".button").on("click", ".button", function(e){
     e.preventDefault(); // stop probagation if its button or a href
     // your code here  
 });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接