简体   繁体   中英

class .on(click) failing when html inside is changed

I have a .on(click) perfectly working the first time, but fails the second, in the way I describe below. This is the code:

$('.inline-edit').on('click', function() {
       if (!$(this).find(':input').length) {
             var current_val = $(this).find('span').html();
             $(this).html('<input type="text" class="txt" maxlength="27" value="' + current_val + '"/>');

             //On outside click, cancel
             $(this).unbind('clickoutside').bind('clickoutside', function(event) {
                  cancelEdit($(this), current_val);
             })
        }
});

When the <td> that has the class inline-edit are clicked, the value in the inner span is obtained, and an input is enabled. This way the user can do an inline edit. When the user clicks outside the <td> , the edit is canceled, calling cancelEdit(), which is:

function cancelEdit(element, value) {
    $(element).html('<span>' + value + '</span><img id="pencil_edit" src="/images/pencil_edit.png">');
}

The cancelEdit function returns the <td> to its original form, which is:

<td class="inline-edit">
     <span>abcdpqsdfsdfsdfrstuvwxyz<?php echo $i?></span>
     <img id="pencil_edit" src="/images/pencil_edit.png"/>
</td>

The problem is that after cancelEdit is called, now when the user clicks on the <td> , if they click over the <span> part (the text), the .on('click') function does not work properly, because the <span> element is being obtained, instead of the <td> . This however only happens the second time, even though the html is exactly the same as the first time. Why is this happening?

You need to stopPropagation I think fiddle :

$('.inline-edit').on('click', function(ev) {
       var td = $(this);
       if (!td.find(':input').length) {
             var current_val = td.find('span').html();
             td.html('<input type="text" class="txt" maxlength="27" value="' + current_val + '"/>');

             //On outside click, cancel
             td.one('clickoutside', function(event) {
                  cancelEdit(td, current_val);
             })
        }
    ev.stopPropagation();
});

function cancelEdit(element, value) {
    $(element).html('<span>' + value + '</span><img id="pencil_edit" src="http://placehold.it/20">');
}

I also set a variable for the element because there's really no need to keep calling $(this) , over and over.

Try this:

$('body').on('click', '.inline-edit', function() {
       if (!$(this).find(':input').length) {
             var current_val = $(this).find('span').html();
             $(this).html('<input type="text" class="txt" maxlength="27" value="' + current_val + '"/>');

             //On outside click, cancel
             $(this).unbind('clickoutside').bind('clickoutside', function(event) {
                  cancelEdit($(this), current_val);
             })
        }
});

I had accepted another answer, which works, but this is superior:

    $('.inline-edit').on('click', function(ev) {
       var td = $(this);
       if (!td.find(':input').length) {
             var current_val = td.find('span').html();
             td.html('<input type="text" class="txt" maxlength="27" value="' + current_val + '"/>');

             //On outside click, cancel
             td.unbind('clickoutside').bind('clickoutside', function(event) {
                  cancelEdit(td, current_val);
             })
        }
    });

I removed the event.stopPropagation() from above, which is not needed if cancelEdit looks like this:

function cancelEdit(element, value) {
    $(element).html('<span>' + value + '</span><img id="pencil_edit" src="/images/pencil_edit.png">');
    $(element).unbind('clickoutside');
}

The trick is unbinding the clickoutside, otherwise it remains binded to the element, even with the new html. Hope that helps someone in a similar situation.

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