Reputation: 393
I might just blame this on lack of sleep, but I'm having a hell of a time removing a class from some links.
Here's what's happening: I'm adding a class to a bunch of links when I check a checkbox, and then I hope to remove remove the class by unchecking the checkbox.
Also involved: Changing a class on the checkbox, which does work when I uncheck it. It just doesn't also remove the classes.
$(document).ready(function() {
var revealer = $('.revealer .reveal');
var hider = $('.revealer .hide');
var days = $('.days li a');
var revealed = $('.days li a.revealed');
$(revealer).change(function() {
$(this).toggleClass('reveal hide');
$(days).each(function(i) {
var day = $(this);
setTimeout(function() {
// $(day).toggleClass('revealed'); Toggle would work, but I don't want the delay when removing the class
$(day).addClass('revealed');
}, 300 * i);
});
});
$(hider).change(function() {
$(this).toggleClass('reveal hide');
$(revealed).removeClass('revealed');
});
});
In the jsFiddle, each link's background fades to black, one at a time. That much works. Unchecking should fade them all back to normal at once, but it doesn't.
Upvotes: 0
Views: 15327
Reputation: 32076
There is no element with .hide
as a class, so hider
is never populated. As a quick and dumb fix, change
$(day).addClass('revealed');
to
$(day).toggleClass('revealed');
and delete your $(hider).change
function
Then the checkbox in the fiddle works to some extent, and I'm sure you can figure it out from there.
Upvotes: 0
Reputation: 957
As others have pointed out, your code has the following issue:
2.Else you can use an id selector on the checkbox and bind your functions accordingly.
Upvotes: 0
Reputation: 34072
The problem is that you're trying to cache states, rather than elements.
At the start of your script you cache $('.revealer .reveal')
and $('.revealer .hide')
, which are states that one element toggles between. It just doesn't work this way.
What happens is that you cache the matched element as revealer
, and bind the first change
function to it. What you think you're caching as hider
is an empty set, as there is no matching element at the time your script loads. So your 2nd bind does nothing.
What you should do instead is change your change
function to react differently based on the current class of the .revealer
, or use live
in place of typical binding, which does essentially what you are trying to do (essentially it watches for selector patterns, rather than binding to elements).
Upvotes: 1
Reputation: 434955
Your problem is that there is no .revealer .hide
when this runs:
var hider = $('.revealer .hide');
So hider
is an empty list. You have similar problems with your other selectors: selectors match elements in the DOM as the DOM is when you use the selector. So when you say $('.revealer .hide').change(...)
you're binding a change handler to whatever elements currently match .revealer .hide
, if the elements that match change in the future then your change handler will not be bound to them (but see below for the standard solution to this sort of problem); similarly, if you remove the hide
class from your checkbox and then put it back later (i.e. toggleClass
) then your original change handler will still be bound to your checkbox: changes to the element's classes do not affect which handlers are or are not bound to it.
If we get rid of your cached selectors and switch your change handlers to use live
then things will work:
$('.revealer .reveal').live('change', function() {
$(this).toggleClass('reveal hide');
$('.days li a').each(function(i) {
var day = $(this);
setTimeout(function() {
day.addClass('revealed');
}, 300 * i);
});
});
$('.revealer .hide').live('change', function() {
$(this).toggleClass('reveal hide');
$('.days li a.revealed').removeClass('revealed');
});
Live version: http://jsfiddle.net/ambiguous/FaZkR/
The live
and delegate
functions act as proxies, they capture and redirect events based on the current state of the DOM rather than the state of the DOM when you are initially called.
Upvotes: 2