jQuery - keep active page highlighted in navigation menu even with rollover effects

I’m building a WordPress site with a nice jQuery effect that fades/unfades images within a navigation menu on rollover. So when the mouse moves off the image, the colored image should fade back to reveal the original non-colored image. This works perfectly as-is, but client wants the active page to keep its colored/ highlighted menu image when mouse has moved off of it.

The bolded line of the code is where I tried to set that up…

<?php wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary' ) ); ?>		

		<script type="text/javascript"><!-- this is from http://jqueryfordesigners.com/image-cross-fade-transition/-->
		// make nav images highlight on hover
		// when the DOM is ready:
		$(document).ready(function () {
		   // find the navigation elements and hook the hover event
		   $('#mainmenu li').hover(function() {
    		  // on hovering over, find the element we want to fade *up*
    		  var fade = $('> div', this);
    
    		  // if the element is currently being animated (to a fadeOut)...
    		  if (fade.is(':animated')) {
      		    // ...take it's current opacity back up to 1
     		    fade.stop().fadeTo(250, 1);
    		  } else {
      		    // fade in quickly
      		    fade.fadeIn(250);
    		  }
  		}, function () {
    		  // on hovering out, fade the element out
    		[B]if (!is_page(current)){[/B]  
			var fade = $('> div', this);
    		  	if (fade.is(':animated')) {
    		    	fade.stop().fadeTo(3000, 0);
    			} else {
      		  	// fade away slowly
      		  	fade.fadeOut(2000);
			}
    		}
  	     });
	});
	</script>

		<ul id="mainmenu">
			<li id="home">
				<a href="/home"><img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/sara_inactive.png" alt="home" width="152" height="309" /></a>
				<div>
   					<a href="/home"><img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/sara_active.png" alt="home" width="152" height="309" /></a>
  				</div>	
			</li>
			

WordPress should know whether the page is ‘current’ or not, so why doesn’t this work? Currently the nav images remain highlighted when the mouse moves away. If I remove my attempt (the bolded line of code) then nav rollovers work beautifully, but active page still isn’t represented with a colored nav menu image.

I think the problem is because you’re trying to mix PHP and JavaScript. WordPress is PHP, fading and animating is JavaScript. So you’re right, WordPress should (and does) know whether the page is current or not. However, once WordPress has built the page and sent it, and the JS has started executing, you no longer have access to its nice “is_page” function.

But if this is your main navigation, then WordPress should be giving the current page’s link a class of some kind (“current_page_item” or something like that, you’ll have to check). So you can change your JS to the following:


if (!$(this).hasClass('current_page_item')) {
    /* fade stuff */
}

Thank you. That all makes sense…but I don’t see that the active navigation menu item has any class added to it. I’m looking for this in Firebug, in the CSS panel. Where else would I look to detect the class name given to the active page?

It should be on the <li> that contains the <a>, something like “current-menu-item” or “current-page-item”

But it’s possible that you’re using a theme that doesn’t do that. If that’s the case, then you might have to edit the header file. (There could be a way to simply turn it on in the Admin section, but I’m not familiar enough with WP to say for sure.)

I see the problem a bit clearer now, but not the proper solution. I had two navigation menus on this page: One was text navigation, which sat above the image navigation. The image nav has the jQuery script that I listed in the code block in my first post. The text navigation was controlled by the WP menu feature. The “current-menu-item” class was being assigned by WP to the text navigation, and since it wasn’t applied to the images of course the images didn’t know to show their colored state for the active page.

I’ve now combined the two navigations into one, but couldn’t think of a way to do it inside the WP ‘menus’ feature so I had to comment-out that part of the code. So now the text and image navs are combined and both fade-in/fade-out with the jQuery, but the original problem remains – the active page is not identified by any class, and so it isn’t differentiated from the other pages. Probably a simple javascript (or jquery) change but I’m a novice at this.

	<?php /* wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary' ) ); */ ?> 
		
		<script type="text/javascript"><!--http://jqueryfordesigners.com/image-cross-fade-transition/-->
		// make nav images highlight on hover
		// when the DOM is ready:
		$(document).ready(function () {
		   // find the navigation elements and hook the hover event
		   $('#mainmenu li').hover(function() {
    		  // on hovering over, find the element we want to fade *up*
    		  var fade = $('> div', this);
    
    		  // if the element is currently being animated (to a fadeOut)...
    		  if (fade.is(':animated')) {
      		    // ...take it's current opacity back up to 1
     		    fade.stop().fadeTo(250, 1);
    		  } else {
      		    // fade in quickly
      		    fade.fadeIn(250);
    		  }
  		}, function () {
    		  // on hovering out, fade the element out
    		if (!$(this).hasClass('current_page_item')){  
			var fade = $('> div', this);
    		  	if (fade.is(':animated')) {
    		    	fade.stop().fadeTo(3000, 0);
    			} else {
      		  	// fade away slowly
      		  	fade.fadeOut(2000);
			}
    		}
  	     });
	});
	</script>

	<ul id="mainmenu">
		<li id="home">
			<a href="/home">Home<img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/sara_inactive.png" alt="home" width="152" height="309" /></a>
			<div>
   				<a href="/home"><img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/sara_active.png" alt="home" width="152" height="309" /></a>
  			</div>	
		</li>
			
		<li id="about">
			<a href="/about">About<img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/david_inactive.png" alt="about" width="152" height="309" /></a>	
			<div>
   				<a href="/about"><img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/david_active.png" alt="home" width="152" height="309" /></a>
  			</div>						
		</li>
		<li id="store">
			<a href="/store">Store<img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/canyon_inactive.png" alt="" width="152" height="309" /></a>
			<div>
   				<a href="/store"><img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/canyon_active.png" alt="home" width="152" height="309" /></a>
  			</div>							
		</li>
		<li id="information"><a href="/information">Information
			<img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/wading_inactive.png" alt="" width="152" height="309" /></a>
			<div>
   				<a href="/information"><img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/wading_active.png" alt="home" width="152" height="309" /></a>
  			</div>							
		</li>
		<li id="contact"><a href="/contact">Contact
			<img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/wall_inactive.png" alt="" width="152" height="309" /></a>
			<div>
   				<a href="/contact"><img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/wall_active.png" alt="home" width="152" height="309" /></a>
  			</div>							
		</li>
	</ul>
				
	</div><!-- #access -->

Still looking for help with this. I’ve got it a little closer to what I need, but its not quite there yet. The mouseover effects work; the assignment of the “current_page_item” class works; but the current_page_item does not fade-in until you mouse over it after the page reloads. In other words: click the “about” page link and that does gain the “current_page_item” class, but the CSS involved in raising the opacity of the colored image does not take effect. The image only fades-in when you trigger it with the hover function.

<?php /* wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary' ) ); */ ?> 
		
				
		<script type="text/javascript">
		// when the DOM is ready:
		$(document).ready(function () {
			//Toggle Class on Click
			$("#mainmenu li").click(function() {				
				$('#mainmenu li:current_page_item').removeClass(function() {
          				return $(this).prev().attr('class');
        			});        		
				$(this).addClass("current_page_item");
			});
		});
		</script>


		<script type="text/javascript"><!--http://jqueryfordesigners.com/image-cross-fade-transition/-->
		// make nav images highlight on hover
		// when the DOM is ready:
		$(document).ready(function () {
		   // find the navigation elements and hook the hover event
		   $('#mainmenu li').hover(function() {
    		  // on hovering over, find the element we want to fade *up*
    		  var fade = $('> div', this);
    
    		  // if the element is currently being animated (to a fadeOut)...
    		  if (fade.is(':animated')) {
      		    // ...take it's current opacity back up to 1
     		    fade.stop().fadeTo(250, 1);
    		  } else {
      		    // fade in quickly
      		    fade.fadeIn(250);
    		  }
  		}, function () {
    		  // on hovering out, fade the element out
    		if (!$(this).hasClass('current_page_item')){  
			var fade = $('> div', this);
    		  	if (fade.is(':animated')) {
    		    	fade.stop().fadeTo(3000, 0);
    			} else {
      		  	// fade away slowly
      		  	fade.fadeOut(2000);
			}
    		}
  	     });
	});
	</script>

	

		<!-- to highlight the current page you need to add the class 'current_page_item' both on the client side (accomplished above) and on the server side. See http://www.vanseodesign.com/wordpress/hightlight-current-page-wordpress/ for how I did the server side class assignment below.-->
		<ul id="mainmenu">
			<li<?php if ( is_front_page()) { echo ' class="current_page_item"'; } ?> id="home">
				<a href="/home">Home<img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/sara_inactive.png" alt="home" width="152" height="309" /></a>
				<div class="colorImg">
   					<a href="/home"><img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/sara_active.png" alt="home" width="152" height="309" /></a>
  				</div>	
			</li>
			
			<li<?php if ( is_page('about')) { echo ' class="current_page_item"'; } ?> id="about">
				<a href="/about">About<img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/david_inactive.png" alt="about" width="152" height="309" /></a>	
				<div class="colorImg">
   					<a href="/about"><img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/david_active.png" alt="home" width="152" height="309" /></a>
  				</div>						
			</li>
			<li <?php if ( is_page('store')) { echo ' class="current_page_item"'; } ?> id="store">
				<a href="/store">Store<img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/canyon_inactive.png" alt="" width="152" height="309" /></a>
				<div class="colorImg">
   					<a href="/store"><img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/canyon_active.png" alt="home" width="152" height="309" /></a>
  				</div>							
			</li>
			<!-- the WP function is_home() refers to the page with the blog posts...which is not always the home page -->
			<li<?php if ( is_home()) { echo ' class="current_page_item"'; } ?>  id="information"><a href="/information">Information
				<img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/wading_inactive.png" alt="" width="152" height="309" /></a>
				<div class="colorImg">
   					<a href="/information"><img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/wading_active.png" alt="home" width="152" height="309" /></a>
  				</div>							
			</li>
			<li<?php if ( is_page('contact')) { echo ' class="current_page_item"'; } ?>  id="contact"><a href="/contact">Contact
				<img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/wall_inactive.png" alt="" width="152" height="309" /></a>
				<div class="colorImg">
   					<a href="/contact"><img src="<?php bloginfo(url); ?>/wordpress/wp-content/uploads/2011/09/wall_active.png" alt="home" width="152" height="309" /></a>
  				</div>							
			</li>
		</ul>
				
		</div><!-- #access -->

and the style rule is…

.current_page_item .colorImg a img{
	background-color:none;
	opacity:.99;
	filter:Alpha(opacity=99); /* IE8 and earlier */
}

Can you post a link to a live example?

david eisenbart dot com

The reason the color image isn’t showing is because of this rule, in your styles:


#home div, #about div, #store div, #information div, #contact div {
    position: absolute;
    top: 30px;
    left: 0;
    display: none; /* <-- this line right here */
}

If you just want the color image to be on by default, you’ll need to counteract that “display:none”


.current_page_item .colorImg { display: block !important }

But if, instead, you wanted it to fade in, you’ll have to go to your JavaScript. (I’m pretty sure this works, but I couldn’t really test on your site.) Just include the following line in your “$(document).ready” chunk that starts at line 91:


$('.current_page_item .colorImg').fadeIn(250);

Hope this helps.

The JavaScript option didn’t seem to work (though that could just be due to my low level of JS skill…I tried it several ways, and in several places).

The CSS change worked well though! The fading would be a nice touch, but after struggling with this for so long I’m just happy to have it finally work!

Thanks so much for staying with me on this, and all your efforts to help me out!