jQuery selectors are ignoring the classes that are manipulated after the page loads
I have some buttons that when clicked, invoke jQuery to remove and replace their class. The jQuery.mouseover event that I want to call is ignoring the manipulated classes, and only obeying the classes from the page load.
Here's an example JSFiddle
Details below:
I have a row of buttons that, when rolled over invoke some jQuery to add a .highlighted class to objects elsewhere on the page:
Here's example HTML:
<ul id="portfolioLinks">
<li class="activeButton kittens"><a class="kittens" href="#"></a></li>
<li class="activeButton otters"><a class="otters" href="#"></a></li>
<li class="depressed donkey"><a class="donkey" href="#"></a></li>
</ul>
and the corresponding jQuery code:
var selectedType = '.' + $(this).attr('class');
$("li.activeButton a").mouseenter(function() {
var selectedType = '.' + $(this).attr('class');
$("div.pageContent div" + selectedType).addClass('highlighted');
});
$("#portfolioLinks a").mouseleave(function() {
$("div.pageContent div").removeClass('highlighted');
});
This works fine on the static content from the page load, but when I click on a button I get
jQuery to add a .depressed
class to $(this)
and give all the others .activeButton
:
$("#portfolioLinks a").click(function() {
$("#portfolioLinks li").addClass('activeButton').removeClass('depressed');
$(this).parent().removeClass('activeButto开发者_如何学Gon').addClass('depressed');
//do some other stuff
});
However, it seems to completely ignore the altered classes, and continues highlighting the divs matching a button that lacks the .activeButton
class.
I spent most of last night and this morning trying to figure this out. I've tried all manner of .not
s, :not
s and if
s, and I'm now completely lost.
Any guidance would be extremely appreciated.
Use .delegate()
here instead, like this:
$("#portfolioLinks").delegate("li.activeButton a", {
mouseenter: function() {
var selectedType = '.' + $(this).attr('class');
$("div.pageContent div" + selectedType).addClass('highlighted');
},
mouseleave: function() {
$("div.pageContent div").removeClass('highlighted');
});
Here's your fiddle updated with the above code, working.
The issue is that when you do $("li.activeButton a")
you're not binding anything to the class, you're binding events to the elements you found with the class when it was run...the elements now have event handlers bound. Any changes in the future are irrelevant, the handlers are bound.
With .live()
and .delegate()
however, the selector is checked when the event happens, so it does matter that the class changed. As a bonus, it's also cheaper for many elements, since there's one set of handlers on #portfolioLinks
.
If using jQuery older than 1.4.3, you'll need the non-map form, like this:
$("#portfolioLinks").delegate("li.activeButton a", "mouseenter", function() {
var selectedType = '.' + $(this).attr('class');
$("div.pageContent div" + selectedType).addClass('highlighted');
}).delegate("li.activeButton a", "mouseleave", function() {
$("div.pageContent div").removeClass('highlighted');
});
精彩评论