0

This is related to Click event doesn't work on dynamically generated elements

Basically I tried to expand a collapsed blockquote upon click

replyfix($('#element'));//In the original data, the expander works as intented 

$.ajax({
    url : pageurl,
    success : function (source) {
        $('#element').after(replyfix($(source).find('#element')));
    }
});

function replyfix(reply){
    reply.find('blockquote blockquote').addClass('collapsed').append('<a href="javascript:;" class="expander">click</a>').children('div').hide();
    reply.find('.expander').one('click', function(){
        $(this).parent().find('div').show();
        $(this).parent().find('.expander').remove();
    });
    return reply;
}

My question is that the object should already be created in the ajax request, and that I bind the new data every time they are created. Why would direct binding not work?

At first I thought I did something wrong in my code, so I tried to confirm I binded an event on the newly created object using

console.log($._data(reply.find('.expander')[0], "events"));

and it shows that the new expander already got an click event binded.

update: The above code is what I have used before, that I would like to understand why it won't work.

$('#element').on('click', ".expander", function(){
    $(this).parent().find('div').show();
    $(this).parent().find('.expander').remove();
});

has already solved the problem.

Community
  • 1
  • 1

2 Answers2

0

Use delegate instead. For example.But use need to predefine that before ajax call even if the element is not added yet. Make sure you bind with body like below.

$('body').delegate('ajax added element','click',function(e){
   //do something
})

Other binding in jquery does not work on ajax generated element. That is where the delegate comes in handy. So try to understand jquery delegate binding first.

Wai Yan Hein
  • 13,651
  • 35
  • 180
  • 372
0

Direct binding does work as the testing code

console.log($._data(reply.find('.expander')[0], "events"));

confirms the the binding exists.

In my non-simplified code, I've used the following code to avoid some problem when directly inserting

.after($.parseHTML(replyFix($(this)).wrap('<p/>').parent().html()))

instead of directly

.after(replyFix($(this)))

This caused a re-parse on HTML, creating new object, with no binding at all. The test occurs in replyfix, where the re-parse hasn't happened, the binding it shows is lost with the original parsed replyFix($(this)).