Reputation: 9504
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.
// 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()
.
// 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.
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?
Upvotes: 1
Views: 1008
Reputation: 87073
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();
});
Upvotes: 3
Reputation: 9504
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.
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.
Upvotes: 0