5

I've just encountered a problem in jQuery. I didn't find a solution which was posted already, if there is one, i apologize for my mistake.

I have this DOM:

<div class='usersList list'>                                    
    <div id='7' class='sidebarElement'> <span>user</span></div> 
    <div id='21' class='sidebarElement'><span>user</span></div> 
    <div id='12' class='sidebarElement'><span>user</span></div> 
    <div id='15' class='sidebarElement'><span>user</span></div> 
    <div id='17' class='sidebarElement'><span>user</span></div> 
    <div id='13' class='sidebarElement'><span>user</span></div> 
    <div id='5' class='sidebarElement'> <span>user</span></div> 
    <div id='3' class='sidebarElement'> <span>user</span></div> 
    <div id='4' class='sidebarElement'> <span>user</span></div> 
    <div id='19' class='sidebarElement'><span>user</span></div> 
    <div id='2' class='sidebarElement'> <span>user</span></div> 
    <div id='6' class='sidebarElement'> <span>user</span></div> 
    <div id='18' class='sidebarElement'><span>user</span></div> 
    <div id='16' class='sidebarElement'><span>user</span></div> 
    <div id='14' class='sidebarElement'><span>user</span></div> 
</div>                                                          

It is loaded via AJAX from another file. The problem I've encountered is the following. Here is my JS:

$(document).ready(function () {

    function reloadUsers(query) {
        $.ajax({
            url: 'getLoginUsersAjax.php',
            type: 'GET',
            data: {query: query},
            success: function (data) {
                $('.usersCardAjaxContainer').empty().html(data);
            }
        });
    }

    $(".sidebarElement span").click(function() {
       console.log($(this).parent().attr("id"));
    })

    reloadUsers("");

});

This didn't work, i think because the elements are loaded via AJAX and aren't here yet when the click is parsed or whatever, i don't know how jQuery works internally. My workaround for that was to put the click even into the success branch of the ajax, like this:

success: function (data) {
    $('.usersCardAjaxContainer').empty().html(data);

    $(".sidebarElement span").click(function() {
        console.log($(this).parent().attr("id"));
    })
}

It works, but seems wrong to me. I've looked for other functions or methods which can do that, but i only found live which is deprecated since jQuery 1.7. Is there anything else i can use or will i have to stick with this workaround?

Realitätsverlust
  • 3,941
  • 2
  • 22
  • 46

1 Answers1

6

You can attach the click event to an already existing element, yet make it trigger only on certain children of that element, as follows:

$('.sidebarElement').on('click', 'span', function() {
    //...
});

You can technically attach your event to $('body') even, as long as the second argument (which is a jquery selector) is precise enough. I wouldn't recommend this method though as it surely has a negative impact on performance. For reference, take a look at jquery's .on() function.

afilina
  • 878
  • 1
  • 11
  • 25
UweB
  • 4,080
  • 2
  • 16
  • 28
  • Ah, now i got it, so i attach it to body, but only trigger it on `.sidebarElement span`, right? So my on event is `$('body').on('click', '.sidebarElement span', function() {`, did i understand that right? – Realitätsverlust Sep 16 '14 at 08:08
  • Jup, works with body. Thanks a lot! – Realitätsverlust Sep 16 '14 at 08:12
  • @Y U NO WORK: *Never* use `'body'` for delegated event handlers! Use `document` as the fallback (if nothing closer to the changing elements exists). There is a bug with `body` relating to styling that means events (especially click) will not always work. – iCollect.it Ltd Sep 16 '14 at 08:21
  • @TrueBlueAussie, which jQuery version is that and is that an acknowledged bug? I'm asking because I recently had funny event handler behaviour (`blur()` being triggered with an empty stack trace on focussing an element in a dialogue), with "reversed roles", meaning: The event handler was attached to a an element that was then appended to `body`. – UweB Sep 16 '14 at 08:30
  • I found the problem in practice with recent jQuery versions (no idea if it is an official issue), so now I always use `document` in preference to `body`. `document` has the added bonus that it exists before any DOM is loaded. – iCollect.it Ltd Sep 16 '14 at 08:59