Событие jQuery.on() не работает для динамически добавленного элемента

Я делаю проект, когда целые div с кнопками вставляются динамически, когда пользователь нажимает кнопку, а внутри этого div есть кнопка, которая, когда пользователь нажимает на нее, делает что-то еще, например, предупреждая что-то для пример.

Проблема в том, что когда я нажимаю эту кнопку в динамически добавленном div, ничего не происходит. Событие вообще не срабатывает.

Я попытался добавить этот div внутри HTML и повторить попытку, это событие сработало. Так что я думаю, потому что div динамически добавлен.

Добавленный div имеет класс mainTaskWrapper, а кнопка имеет класс checkButton. Событие подключается с помощью .on() в конце файла script.js ниже.

Здесь мой код:

helper_main_task.js: (что объект, который добавляет div, вам не нужно его читать, так как я думаю, что все это динамически добавлено в div, но я поставлю его если вам нужно)

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: (файл, в котором функция .on() находится внизу)

$(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 the event i'm talking about :
    $("div.mainTaskWrapper").on('click', '.checkButton' , function(){
        alert("test text");
    });
});

Ответы

Ответ 1

Это не похоже на div.mainTaskWrapper.

Из документации (да, это на самом деле жирный шрифт):

Обработчики событий привязаны только к выбранным в данный момент элементам; они должны существовать на странице в момент, когда ваш код выполняет вызов .on().. Чтобы убедиться, что элементы присутствуют и могут быть выбраны, выполните привязку событий внутри документа, готового к обработке для элементов, находящихся в разметке HTML на странице.

[...]

Выбирая элемент, который гарантированно присутствует во время присоединения делегированного обработчика событий, вы можете использовать делегированные события, чтобы избежать необходимости часто присоединять и удалять обработчики событий.

Вместо этого вы можете привязать его к #tasksWrapper:

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

Ответ 2

Вам нужно указать селектор с on (как параметр), чтобы заставить его вести себя как старый метод delegate. Если вы этого не сделаете, событие будет привязано только к элементам, которые в точности совпадают с div.mainTaskWrapper (которые еще не существуют). Вам нужно либо повторно назначить событие после добавления новых элементов, либо добавить событие к уже существующему элементу, например, #tasksWrapper или самому документу.

См. "Прямое и делегирование событий" на на этой странице.

Ответ 3

Я знаю, что это старый пост, но может быть полезен для всех, кто сталкивается...

Вы можете попробовать:

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

Вот пример: https://jsfiddle.net/8b0e2auu/