tags:

views:

238

answers:

4

I'm making a simple navigation menu for a site. You create an ul with id menu, and should be pretty simple from there. I have some simple css to give all the lis the correct background image, then some jQuery to change the look of an li when the user mouses over. It works pretty well, but there's one problem. When the user clicks on a link directly, rather than clicking in the box around it, and then uses the browser's back button, things go wrong. When the user hovers over this time, the entire li goes completely blank, but it's fine once the user mouses away. Does anyone know what may cause this strange behavior? (Note, every once in a while, mousing over causes a li to flicker, especially if it's one of the bottom two lis. I thought this was normal, but maybe it could be helpful in diagnosing the problem.)

<html>
<head>
<title>Menu Test</title>
<style type="text/css">
ul#menu{width: 185px; margin: auto; text-align: center; color: #fff; list-style-type: none;}

ul,li,h2{padding: 5px 0 0 0; margin: 0;}

li h2{height: 49px; background: url('top.png'); vertical-align: middle;}
li.link{height: 30px; background: url('link.png');}
li.link a{color: white; text-decoration: none;}
li.bottom{height: 25px; background: url('bottom.png');}
</style>

<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript">
 $(document).ready(function(){
  $(".link").mouseover(function(){ //highlight on mouseover
   $(this).css({background: "url('file:///Users/J/Desktop/DHTML/Menu/linkselect.png')"});
  })
  $(".link").mouseout(function(){ //un-highlight on mouseout
   $(this).css({background: "url('./link.png')"});
  })
  $(".link").click(function(){ //go to site on click, even if click isn't on link
   window.location = $(this).find("a").attr("href");
  })
 })
</script>
</head>
<body>

<ul id="menu">
 <li><h2>Menu</h2></li>
 <li class="link"><a href="http://google.com/"&gt;Google&lt;/a&gt;&lt;/li&gt;
 <li class="link"><a href="http://norwegianrecycling.multiply.com/"&gt;Norwegian Recycling</a></li>
 <li class="link"><a href="http://www.jquery.com/"&gt;jQuery&lt;/a&gt;&lt;/li&gt;
 <li class="link"><a href="http://www.apple.com/"&gt;Apple&lt;/a&gt;&lt;/li&gt;
 <li class="link"><a href="http://www.ubuntu.com"&gt;Ubuntu&lt;/a&gt;&lt;/li&gt;
 <li class="link"><a href="http://www.firefox.com/"&gt;Firefox&lt;/a&gt;&lt;/li&gt;
 <li class="link"><a href="http://www.youtube.com/"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
 <li class="bottom"></li>
</ul>

</body>
</html>
+1  A: 

I know this isn't exactly an answer to your question, but changing the CSS properties of an element when hovered can be done entirely in CSS. For your example, your CSS would be something like:

.link {
  background: url('./link.png');
}
.link:hover {
  background: url('file:///Users/J/Desktop/DHTML/Menu/linkselect.png');
}

I think you could also wrap the <a> tag around the <li> tag, such that the whole list item is the link (eliminating the need for the $(".link").click(...) code).

Oops, can't wrap <a> around <li>, but as Oli mentioned, you can do this in CSS:

.link a {
  display: block;
}
Kip
+5  A: 

You know you can do everything you're doing there with just CSS and HTML?

  • Set the a to display:block so that it fills the li
  • Set a :hover state on a to change the background.
  • ???
  • Profit.
Oli
You'll probably want to set height and line-height on the link (a, not .link) elements too.
Oli
+1 for the ??? Profit part. :)
Paolo Bergantino
I'm not sure that :hover will work in older browsers like IE6 while the javascript method would. That has been my experience in the past when dealing with IE6.
Dan McNevin
I'm 99% sure the :hover works in IE6.
rmeador
I don't mean to sound rude, but this is not answering his question. Offering another solution wasn't the request. I am actually curious why the behavior would be different after hitting the back-button.
Jonathan Sampson
From what I have read, in IE6, :hover is supported on anchors but not things like li,tr, etc.. I have to support IE6 and have had to write javascript workarounds for this.
Dan McNevin
you may be right that it only works on anchors... I, too, have the misfortune of being forced to support IE6, and we use it all the time, but probably only on anchors.
rmeador
a:hover works - that's what I'm suggesting. Make the <a> a block, make it fill the <li> and give it the background instead of the <li>
Oli
IE6 does not support :hover on anything other then a. Making the a as big as the li (using lineheight and display:block as Oli suggests) should work.
Pim Jager
+2  A: 

The following works. I'll leave the CSS details to you. Note also, as other have pointed out, you CAN do this with pure CSS and get the same result. But since that is not what you asked for, I will respect your request and give jQuery.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Default Web Project - www.SampsonResume.com</title>
    <style type="text/css">
      .ul {list-style:none;margin:0;padding:0;border:1px solid #CCCCCC;}
      li.link {background-color:#000000;padding:10px;}
        li a {color:#ffffff;text-decoration:none;}
      li.on {background-color:#f1f1f1;cursor:pointer;}
        li.on a {color:#000000;}
    </style>
    <script src='scripts/jquery/jquery-1.3.min.js' type='text/javascript'></script>
      <script type="text/javascript">
        $(document).ready(function(){
          $("li.link").each(function(){
            $(this).hover(
              function(){$(this).addClass("on");},
              function(){$(this).removeClass("on");}
            );
           $(this).click(function(){
             window.location = $(this).find("a").attr("href");
           });    
         });
       });
     </script>
  </head>
  <body>
    <ul>
      <li class="link"><a href="http://www.google.com"&gt;Google&lt;/a&gt;&lt;/li&gt;
      <li class="link"><a href="http://www.yahoo.com"&gt;Yahoo&lt;/a&gt;&lt;/li&gt;
      <li class="link"><a href="http://www.SampsonVideos.com"&gt;SampsonVideos&lt;/a&gt;&lt;/li&gt;
    </ul>
  </body>
</html>
Jonathan Sampson
The "each" is completely unnecessary, isn't it? That is what chaining is for: $('li.link').hover(...).click(...);
Prestaul
I do think that this code will fix his problem though. He needs to use the "hover" method or use the mouseenter/mouseleave events in place of mouseover/mouseout. +1 from me!
Prestaul
Prestaul, I used .each() as a habit, as I generally do more with my links than merely adding classes.
Jonathan Sampson
A: 

Oh well, I said I wouldn't give a CSS-Solution, but here it is anyway:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Default Web Project - www.SampsonResume.com</title>
    <style type="text/css">
      ul {list-style:none;margin:0;padding:0;border:1px solid #CCCCCC;}
      li {margin:0;padding:0;}
        li a {display:block;background-color:#FFF;color:#000;text-decoration:none;}
      li a:hover {color:#FFF;background-color:#000;}
    </style>
  </head>
  <body>

    <ul>
      <li><a href="http://www.google.com"&gt;Google&lt;/a&gt;&lt;/li&gt;
      <li><a href="http://www.yahoo.com"&gt;Yahoo&lt;/a&gt;&lt;/li&gt;
      <li><a href="http://www.SampsonVideos.com"&gt;SampsonVideos&lt;/a&gt;&lt;/li&gt;
    </ul>

  </body>
</html>
Jonathan Sampson