You're not the first person who has gotten tripped up on this point. Because
jQuery uses CSS-like selectors, it's easy to assume that they work like they
do in CSS stylesheets. But there is a key difference.

When you use a CSS selector in a stylesheet, that selector applies to all
matching elements, regardless of when or how the elements are made to match.

For example, if you have this style:

.hideme { display: none; }

Then any element with the "hideme" class will be hidden, even if you add
that class to an element dynamically. The element will be hidden at the time
you add the class.

But when you use a selector in jQuery, it matches only those elements that
satisfy the selector *at the time you execute the code*. The selector isn't
saved away to be magically applied to elements that may later match.

So, in your ready function, when you use $(".sidebarContent
h3.headerHidden"), that matches only the elements that have the headerHidden
class at page load time, not any elements that may later have that class
added.

One easy way to fix your code would be something along these lines:

$(document).ready(function(){
        $(".sidebarContent h3").click(function(){
                var $this = $(this);
                if( $this.is('.headerShown') ) {
                        $this.next().slideUp("slow");
                        $this.removeClass('headerShown');
                        $this.addClass('headerHidden');
                }
                else {
                        $this.next().slideDown("slow");
                        $this.removeClass('headerHidden');
                        $this.addClass('headerShown');
                }
                return false;
        });
});

-Mike

> From: SteelSoftware
> 
> I'm trying to show/hide sections of my site using jQuery, but 
> also changing the class of the element I'm targeting when the 
> slide is toggled. This is the HTML
> 
> <div class="sidebarContent">
>             <h3 class="headerShown">Top Scorer</h3>
>             <div class="content">
>                 The club's top scorer is:
>                 <ul>
>                     <li><a href="xxxxxxxxxxx">Urn </a> - 18</li>
>                 </ul>
>             </div>
>          </div>
> 
> The jQuery I'm using is:
> $(document).ready(function(){
>       $(".sidebarContent h3.headerShown").click(function(){
>               $(this).next().slideUp("slow");
>               $(this).removeClass('headerShown');
>               $(this).addClass('headerHidden');
>               return false;
>       });
>       $(".sidebarContent h3.headerHidden").click(function(){
>               $(this).next().slideDown("slow");
>               $(this).removeClass('headerHidden');
>               $(this).addClass('headerShown');
>               return false;
>       });
> });
> 
> Basically, when it's hidden, the class changes, making the 
> background image on the h3 element change. My problem is that 
> although the jQuery script says it's changing the class to 
> 'headerHidden', it won't slide down because it's going on the 
> original DOM, not the current one.
> 
> I'm sure the answer is to have some sort of conditional 
> statement in it, but since very few jQuery statements return 
> a boolean, I'm not sure how to.

Reply via email to