0

There are several posts dealing with on() and DOM elements added through JavaScript, but none see to apply to my situation.

After <li class="prepend"><a href="#">x</a></li> is prepended inside a <ul>, I can't seem to attach events to it.

JS:

$('.categories > li a').on('click', function(event){
    event.preventDefault();
    if ($(this).parent().is('.more')) {
        $(this).siblings('ul').prepend('<li class="back"><a href="#">&lt; ' + $(this).html() + '</a></li>')
    }  else if ($(this).parent().is('.back')) {
        console.log('it worked')
    }
})

HTML:

<ul class="categories">
    <li class="selected">
        <a href="#">1 Featured</a>
    </li>
    <li>
        <a href="#">1 Popular Genres</a>
    </li>
    <li class="more">
        <a href="#">1 My Rooms &gt;</a>
        <ul>
            <li><a href="#">2 Tristique Cras</a></li>
            <li><a href="#">2 Porta Etiam &gt;</a></li>
            <li><a href="#">2 Mattis Tortor</a></li>
            <li class="more">
                <a href="#">2 Cras Fermentum &gt;</a>
                <ul>
                    <li><a href="#">3 Tristique Cras</a></li>
                    <li><a href="#">3 Porta Etiam</a></li>
                    <li><a href="#">3 Mattis Tortor</a></li>
                    <li><a href="#">3 Cras Fermentum</a></li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

Even this simple event won't see clicks to elements with class .back

$('a').on('click', function(event){
    event.preventDefault();
    console.log(this);
})
nipponese
  • 2,813
  • 6
  • 35
  • 51
  • 2
    Are you perhaps looking for the three-argument variant of `on` that uses delegation to handle dynamically-added elements? `$(parent).on(eventType, targetSelector, handler)`, e.g., `$('.categories').on('click', 'li a', function() { });` – apsillers Jul 31 '13 at 00:14
  • @apsillers I'm not sure I understand the difference. One bubbles up only one level, and one is document-wide. Shouldn't I at least be seeing something/anything in console log? – nipponese Jul 31 '13 at 00:17
  • @apsillers btw, this does work, but I don't understand why. – nipponese Jul 31 '13 at 00:20
  • 2
    When you run `$('.categories > li a')` you select all the elements *currently on the page* that match your selector, and attach listeners to them. Elements that are added later don't get selected (unless you run another selector and attach more events). The three-arg variant `on` works on a *container* and says, "*Hey container, if any of your **descendants** ever get clicked (regardless of when they were added), here's how to handle that event.*" – apsillers Jul 31 '13 at 00:23
  • See [Direct vs. Delegated - jQuery .on()](http://stackoverflow.com/questions/8110934/direct-vs-delegated-jquery-on) for a good explanation. – apsillers Jul 31 '13 at 00:26
  • 1
    possible duplicate of [Dynamic html page creation with jquery](http://stackoverflow.com/questions/17407808/dynamic-html-page-creation-with-jquery) – Omar Jul 31 '13 at 00:29
  • +1 to @apsillers you explained the problem perfectly! – Lughino Jul 31 '13 at 00:55
  • this is not the same as $(this) – carter Jul 31 '13 at 01:00
  • @apsillers Thanks, that makes sense! One question: I see a lot of people selecting document instead of a child container. Is there a reason I should use a container further down the DOM? – nipponese Jul 31 '13 at 20:22
  • 1
    I'll answer you... the reason is a single question of speed. Imagine that if you enter "document" he goes to look again at all the DOM in search of new elements, while if you're sure that the new elements must be searched only within a container element, then you can enter that in order as to speed up the search for new elements. I hope I explained well .. – Lughino Jul 31 '13 at 20:42

1 Answers1

0

Watch this: http://jsfiddle.net/lughino/8uzgd/

in order to capture the elements that are created after the page loads, you need to call on method in this way:

$(document).on('click', '.categories > li a', function(event){

To learn more take a look at the documentation

Lughino
  • 4,060
  • 11
  • 31
  • 61
  • While this may work, there isn't any explanation as to why. I guess it seems implicit that if I'm using the feature that I have at least tried to understand the docs on `on()`, so it would have been better if you had tried an alternative explanation. – nipponese Jul 31 '13 at 20:25
  • Thank you for reporting. In fact I wanted to add it to the answer but then I saw in the comments that I had already explained and I did not want to repeat myself! – Lughino Jul 31 '13 at 20:31