简体   繁体   中英

click function within another click function is called multiple times

i am in touch with jquery for the first time and ran into this: I am trying to create a dynamic input-form. A click function creates a new list-item with another click function nested into it (to provide a remove function for the clicked item).

When i execute the nested click function it appears to be called the number of instances that have been created of it.

Here is the code (i tried to remove as much as possible, but i am not quite sure where the error is - so i guess i left to much stuff in - sorry).

$("#addIngredient").click(function(e){
    e.preventDefault();

    var prefix = "form-"
    var last = $("#IngredientForm ul li").last().html();

    $("#IngredientForm ul").append("<li>"+last+"</li>");

    var name = $("#IngredientForm ul li:last input").attr("name");
    name = name.replace(prefix,'');
    var count = parseInt(name[0]);
    count += 1;


    $("#IngredientForm ul li:last input").attr("name",prefix+count+"-weight")
    $("#IngredientForm ul li:last select").attr("name",prefix+count+"-ingredient")
    $("#IngredientForm ul li:last input").attr("id","id_"+prefix+count+"-weight")
    $("#IngredientForm ul li:last select").attr("id","id_"+prefix+count+"-ingredient")
    $("#id_form-TOTAL_FORMS").val(count+1);

    $(".deleteIngredient").click(function(e){
        e.preventDefault();

        var aktuell = $(this).closest('li');
        var formCount;
        name = aktuell.children('input').attr("name");
        name = name.replace(prefix,'');
        counter = name.replace("-weight",'');
        formCount = parseInt($("#id_form-TOTAL_FORMS").val());

        aktuell.remove();
        --formCount;

        $("#id_form-TOTAL_FORMS").val(formCount);
        for (var i = parseInt(counter); i<formCount; i++){
        var newName = "form-"+(i);
        $("#id_form-"+(i+1)+"-weight").attr("name",newName+"-weight");
        $("#id_form-"+(i+1)+"-ingredient").attr("name",newName+"-ingredient");
        }

    });

 });

This block

$(".deleteIngredient").click(function(e){...

attaches a clickevent to all .deleteIngredient elements, also those created before.

You have to put this block outsite the click event of #addIngredient . You can make the delete event to be attached also to every element added in the future.

$("#addIngredient").click(function(e){
    // ...
});

$(document).on("click", ".deleteIngredient", function(e){
    // ...
});

As the other answers have noted, the click handler is adding a click handler to every .deleteIngredient element every time you run it, which adds multiple handlers to all the previous elements.

When you add a new item to the list, you don't have to add a click handler to it. You can use delegation to create a handler one time that will apply to dynamically-added elements:

$("#IngredientForm").on("click", ".deleteIngredient", function(e) {
    ...
});

See Event binding on dynamically created elements? for more information.

Every time that outer "click" event happens, you're adding another "click" handler for the ".deleteIngredient" element(s). The .click function does not remove previously-assigned event handlers.

You can get rid of old handlers with .unbind or, preferably with new versions of jQuery, .off :

$('.deleteIngredient').unbind('click').click(function(event) {
  // ...
});

No, the thing is, here I think you probably want to bind to the .deleteIngredient button that you're adding for the new ingredient. The code you've got — based on the reference to $('.deleteIngredient') — will affect all of the elements on the page with that class. My guess here is that you're adding a button or something for each <li> . Thus, what you should probably be doing is finding the button inside the newly-added structure:

$('#IngredientForm ul li:last .deleteIngredient').click(function(event) {
  // ...
});

Use this format instead

$("#addIngredient").on('click', function() {
   $(this).off();
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM