简体   繁体   中英

jQuery .on() not firing event handler

Scenario

I have a list of users, within each list item is a <header> and a <div> wrapper - they are siblings:

<li class="user">
    <header>
        // ...
    </header>
    <div class="user-wrapper">
        // ...
    </div>
</li>

I am toggling the div wrapper when the user header is clicked.

What currently works:

// the handler is called
$('li.user > header').live('click', function () {
    $(this).next('.user-wrapper').toggle();
});

As live() has been deprecated and I am using jQuery 1.7.2, I want to use on() .

What does not work:

// Direct style
$('li.user > header').on('click', function () {
    $(this).next('.user-wrapper').toggle();
});

// Delegated style
$('li.user').on('click', 'header', function () {
    $(this).next('.user-wrapper').toggle();
});

In either on() scenario, the anonymous handler function is not being called.

Question

First... why is on() choking?

Second... if/when it works, using the delegate style, can i still reference the header's sibling div in the same manner as above?

[EDITED]

For delegate event handling the syntax of .on() is:

// 'element' must be static and an ancestor to 'target'.
$(element).on(eventName, target, handlerFunction);

Your delegate scenario above should work, assuming your li.user tags are static at the time of binding.

$('li.user').on('click', 'header', function () {
    $(this).next('.user-wrapper').toggle();
});

If you test this in jsFiddle, it works as is. It seems like your li.user elements are being created dynamically.

If li.user is dynamically created then use a different (static) parent selector. If your list ul is always present, for example:

// HTML
<ul class="user-list">
  <li class="user">
    <header>
        // ...
    </header>
    <div class="user-wrapper">
        // ...
    </div>
  </li>
</ul>

// JavaScript
$('ul.user-list').on('click', 'li.user > header', function() {
  $(this).next('.user-wrapper').toggle();
});

Thanks

Lots of gratitude to @thecodeparadox - his answer explains the issue best and is marked as such. My answer below just explains the details of how/why the list items became dynamic.

Further explanation

Knockout.js is being used to template the li elements. This alone was not the issue as the li elements were created before the .on() bindings occurred and are still treated as "static".

The killer was a ko.computed() property on the knockout model. The property reloads the collection here/there. From the moment the collection is reloaded, the scaffolding of the li items is redone and all the .on() break.

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