0

我有一个 div 作为用户执行任务(例如,参加比赛)的按钮,如下所示。

<div id="enter_competition_button" class="option_long hovertext" data-hovertext="Click to enter this competition">Enter This Competition</div>

下图是用户单击上述按钮后插入新竞争对手的 jQuery Ajax。

$("#enter_competition_button").click(function(){
    $.ajax({
        type:"post",
            url:"/caseproject/competition/Controller/ajax/enter_competition.php",
        data:{username:username,competitionId:competitionID,classBelong:classBelong},
        beforeSend: function(){
            $("#enter_competition_button").text("Entering...");
        },
        success: function(data){
            if(data==0){
                $("#enter_competition_button").text("Failed!");
            } else if(data==1){
                $("#enter_competition_button").text("Cancel Entry");
                $("#enter_competition_button").attr("id", "cancel_competition_button");
            } else {
                $("#enter_competition_button").text("Error!");
            }
        }
    });
});

一旦插入成功,它就成功地将 div 的 id 从“enter_competition_button”更改为“cancel_competition_button”。我已经为 id 为“cancel_competition_button”的 div 添加了 jQuery 事件处理程序,如下所示。

$("#cancel_competition_button").click(function(){
    alert("Canceled");
});

但是,当我单击同一个 div(取消条目)时,jQuery 仍将其识别为“enter_competition_button”而不是“cancel_competition_button”,从而执行第二次插入。

有关解决此问题的任何提示?提前致谢。

4

3 回答 3

2

它不会将其“识别”为enter_competition_button. 会发生什么:

给,约翰,拿着这个。你现在叫玛莎。你为什么还拿着它?!?你现在叫玛莎,我没有你,我给了约翰,wtf?

您正在通过其 ID 获取一个元素,然后click在该元素上绑定一个处理程序(不是名称!)。稍后您更改它的名称,但它仍然具有相同的click处理程序。

cancel我假设您在名称更改发生之前绑定了点击处理程序;在这种情况下,你大喊:

玛莎,坚持住!

而且,不出所料,没有人站出来 - 没有元素被称为cancel_competition_button,所以零元素得到了他们闪亮的新click处理程序。


您想要做的是,不是将处理程序绑定到元素,而是使用 jQuery 的“实时”事件来绑定到名称。您可以通过将事件绑定到父级来完成此操作,并使用选择器进行检查。假设你有这样的事情:

<form id="button_holder">
    <div id="enter_competition_button" class="option_long hovertext" data-hovertext="Click to enter this competition">Enter This Competition</div>
</form>

现在你可以这样做:

哟,迈克!每当有人要求约翰,找到他并告诉他这样做。每当有人要求玛莎时,找到并告诉她这样做。

或者,在代码中:

$("#button_holder").
    on("click", "#enter_competition_button", function(){
        // ... your old click handler goes HERE
    }).
    on("click", "#cancel_competition_button", function(){
        alert("Canceled");
    });
于 2013-11-14T09:07:59.320 回答
1

您可以使用event delegation注册事件处理程序来执行此操作:

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

    // Check for the clicked div id here first using `e.target.id`
    if (e.target.id === 'enter_competition_button') {

        // make the ajax call here   
        $.ajax({...});

    } else if (e.target.id === 'cancel_competition_button') {
        alert("Canceled");
    }
});

如果可能,请使用最接近的静态父 ID 或类更改document此处,假设ID为 as的父元素,container代码将修改为:

$('#container').on('click', 'div.option_long', function (e) {

    // Check for the clicked div id here first using `e.target.id`
    if (e.target.id === 'enter_competition_button') {

        // make the ajax call here   
        $.ajax({...});

    } else if (e.target.id === 'cancel_competition_button') {
        alert("Canceled");
    }
});

这会将您的事件附加到元素内的任何 div #container,从而减少检查整个document元素树的范围并提高效率。

于 2013-11-14T09:07:53.907 回答
1

由于cancel_competition_button在您尝试创建事件处理程序时不存在具有 id 的元素,因此您的 jquery 元素选择为空,并且单击处理程序不能附加到任何内容。在 id 更改后将处理程序注册放在成功回调中。使用这种方法时,我还会在其中添加一个取消绑定调用,用于单击处理程序,以避免多次注册。

编辑:虽然这应该可行,但@Amadan 解决方案更优雅、更干净,而且在我看来,这绝对是你应该走的路。

于 2013-11-14T09:11:51.007 回答