Domanda L'evento jQuery .on () non funziona per l'elemento aggiunto dinamicamente


Sto facendo un progetto in cui un intero div con pulsanti viene inserito dinamicamente quando l'utente fa clic su un pulsante, e all'interno di quel div c'è un pulsante, che quando l'utente fa clic su di esso, fa qualcos'altro, ad esempio per avvisare qualcosa.

Il problema è quando premo quel pulsante nel div aggiunto dinamicamente, non succede nulla. L'evento non sparisce affatto.

Ho provato ad aggiungere quel div all'interno dell'HTML e riprovare, l'evento ha funzionato. Quindi credo che sia perché il div è aggiunto dinamicamente.

Il div aggiunto ha una classe mainTaskWrappere il pulsante ha una classe checkButton. L'evento è allegato utilizzando .on() alla fine di script.js file qui sotto.

Ecco il mio codice:

helper_main_task.js: (questo è l'oggetto che aggiunge il div, non devi leggerlo, poiché penso che sia tutto incentrato sul fatto che il div è stato aggiunto dinamicamente, ma lo metto nel caso in cui ne avessi bisogno)

var MainUtil = {
    tasksArr : [],
    catArr : ["all"],
    add : function(){       

        var MTLabel = $("#mainTaskInput").val(),  //task label  
            MTCategory = $("#mainCatInput").val(), //task category 
            MTPriority = $("#prioritySlider").slider("value"),  //task priority     
            MTContents = $('<div class="wholeTask">\
                                <div class="mainTaskWrapper clearfix">\
                                    <div class="mainMarker"></div>\
                                    <label class="mainTaskLabel"></label>\
                                    <div class="holder"></div>\
                                    <div class="subTrigger"></div>\
                                    <div class="checkButton"></div>\
                                    <div class="optTrigger"></div>\
                                    <div class="addSubButton"></div>\
                                    <div class="mainOptions">\
                                        <ul>\
                                            <li id="mainInfo">Details</li>\
                                            <li id="mainEdit">Edit</li>\
                                            <li id="mainDelete">Delete</li>\
                                        </ul>\
                                    </div>\
                                </div>\
                            </div>');


        this.tasksArr.push(MTLabel);

        //setting label
        MTContents.find(".mainTaskLabel").text(MTLabel);        

        //setting category  
        if(MTCategory == ""){
            MTCategory = "uncategorized";
        }
        MTContents.attr('data-cat', MTCategory);
        if(this.catArr.indexOf(MTCategory) == -1){
            this.catArr.push(MTCategory);
            $("#categories ul").append("<li>" + MTCategory +"</li>");
        }
        $("#mainCatInput").autocomplete("option", "source",this.catArr);

        //setting priority marker color
        if(MTPriority == 2){ 
            MTContents.find(".mainMarker").css("background-color", "red");
        } else if(MTPriority == 1){
            MTContents.find(".mainMarker").css("background-color", "black");
        } else if(MTPriority == 0){
            MTContents.find(".mainMarker").css("background-color", "blue");
        }       

        MTContents.hide();
        $("#tasksWrapper").prepend(MTContents); 
        MTContents.slideDown(100);

        $("#tasksWrapper").sortable({
            axis: "y",
            scroll: "true",
            scrollSpeed : 10,
            scrollSensitivity: 10,
            handle: $(".holder")            
        });

    }
};

script.js: (il file in cui la funzione .on () si trova in basso)

$(function(){
     $("#addMain, #mainCatInput").on('click keypress', function(evt){       
        if(evt.type == "click" || evt.type =="keypress"){
            if((evt.type =="click" && evt.target.id == "addMain") ||
                (evt.which == 13 && evt.target.id=="mainCatInput")){    
                    MainUtil.add();                                             
            }
        }
    });

    //Here's the event i'm talking about :
    $("div.mainTaskWrapper").on('click', '.checkButton' , function(){
        alert("test text");
    });
});

15
2017-08-30 23:30


origine


risposte:


Non sembra div.mainTaskWrapper esistere.

Dal documentazione (sì, in realtà è in grassetto):

I gestori di eventi sono associati solo agli elementi attualmente selezionati; devono esistere sulla pagina nel momento in cui il tuo codice effettua la chiamata .on(). Per garantire che gli elementi siano presenti e possano essere selezionati, eseguire il binding degli eventi all'interno di un gestore pronto per il documento per gli elementi presenti nel markup HTML sulla pagina.

[...]

Selezionando un elemento che è garantito sia presente nel momento in cui il gestore eventi delegato è collegato, è possibile utilizzare gli eventi delegati per evitare la necessità di collegare e rimuovere frequentemente gestori di eventi.

Potresti voler legarlo a #tasksWrapper anziché:

$("#tasksWrapper").on('click', '.checkButton' , function(){
    alert("test text");
});

33
2017-08-30 23:33



Devi specificare un selettore con on (come parametro) per farlo comportarsi come il vecchio delegate metodo. Se non lo fai, l'evento sarà collegato solo agli elementi che corrispondono regolarmente div.mainTaskWrapper (che non esiste ancora). È necessario riassegnare l'evento dopo aver aggiunto i nuovi elementi o aggiungere l'evento a un elemento già esistente, ad esempio #tasksWrapper o il documento stesso.

Vedi 'Direct and delegate events' on questa pagina.


3
2017-08-30 23:38



So che questo è un vecchio post ma potrebbe essere utile per chiunque altro si imbatta in ...

Potresti provare:

jQuery('body')on.('DOMNodeInserted', '#yourdynamicallyaddeddiv', function () {
//Your button click event
});

Ecco un rapido esempio: https://jsfiddle.net/8b0e2auu/


3
2017-10-07 16:06