tags:

views:

73

answers:

6

I'm not sure why my event isn't firing? I simply want to change the list style type when the user hovers over an li. It doesn't look like I'm missing anything, but nothing is happening.

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head runat="server">
    <title></title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
    <link href="theme.css" rel="stylesheet" type="text/css" />
</head>
<script type="text/javascript">
  $(".component ol li").hover(function() {
          $(this).css('list-style-type', 'disc');
      }
   );
</script>
<body>
    <form id="form1" runat="server">
     <div class="component">
     <ol>
         <li><a href="#"></a>&nbsp;</li>
         <li><a href="#"></a>&nbsp;</li>
         <li><a href="#"></a>&nbsp;</li>
         <li><a href="#"></a>&nbsp;</li>
         <li><a href="#"></a>&nbsp;</li>
     </ol>
     </div>    
    </form>
</body>
</html>
+9  A: 
<script type="text/javascript">
  $(document).ready(function() {
     $(".component ol li").hover(function() {
          $(this).css('list-style-type', 'disc');
        }
     );
   });
</script>

If you don't have the document.ready, that gets executed before your list items get added to the DOM, so it basically does nothing. Or move that whole section to after the list items.

EDIT: per further discussion: It is best practice to not use document.ready, since it has to wait for everything on the page to finish loading to run. With that said, you can always put these 'initializing' blocks at the end of the html to make sure that all DOM objects are created when this is executed.

Or the second object is to use .live(). This function will attach an event to the result of the selector whenever an element that fits the selector is created. Now you can keep this block at the top and use:

<script type="text/javascript">
   $(".component ol li").live('hover', function() {
      $(this).css('list-style-type', 'disc');
   });
</script>

Now anytime something matches $(".component ol li") is added to the DOM, your hover function will get attached.

shoebox639
Perfect. Thanks.
George
I don't like `document.ready`, if your page hangs to load something it will take a while to the script run. Like the StackOverflow `inbox`, it was using `document ready` and if the page delayed a bit and you clicked the icon you were redirected instead of showing the popup. Now it seems to be fixed.
BrunoLM
Mmm, I agree. But this seems like a simple page that's not making a zillion calls to a zillion different servers. Otherwise, use the second option of taking the block out of document.ready and just put the script block after where you right the list items.
shoebox639
That is untrue. You should have your scripts at the bottom of the page in the first place, which means the DOM elements would exist when they hover is applied. Read what Dave Ward wrote a few weeks ago, http://encosia.com/2010/08/18/dont-let-jquerys-document-ready-slow-you-down/
Chris Love
Im confused about what I said was untrue? About the zillions of calls? about putting script after the dom object is created? I mean the only thing I didn't cover that was in the article was using `.live()`.
shoebox639
A: 

it will work once you write your javascript like this

$(function(){

  $(".component ol li").hover(function() {
          $(this).css('list-style-type', 'disc');
      }
   );
})
tawfekov
A: 

Because you are selecting elements that doesn't exist yet.

This will execute before the element exist (this doesn't work)

<script></script>
<ul></ul>

This will execute after the element is rendered (this works)

<ul></ul>
<script></script>

If you want your script on top you have two choices:

  • Using $(function () { }): Adds an event on DOMready, it means the function will fire when all elements load.
  • Using $().live(): This is going to add an event on the window that will check the target, meaning it is going to work on any element added even after the page is loaded.

Reference

BrunoLM
A: 

Well, it works for me w/o your css : link

Maybe you should show it to us.

Chouchenos
Oh, now I realize... Does JSFiddle add `$(document).ready(function() {...})` automatically ? :S
Chouchenos
A: 

You can use the $.delegate method to create a mouseenter and a mouseleave event handler to manage your hover effect. I know you did not define a hover off handler in your code, but here is how you would do it using delegate, which will work anytime you have elements matching the selectors:

$(".component ol").delegate("li", "mouseenter", function(e) {

$(this).css('list-style-type', 'disc');

});

$(".component ol").delegate("li", "mouseleave", function(e) {

$(this).css('list-style-type', 'circle');

});

Chris Love
+2  A: 

Hi George,

First I would recommend using

 $(document).ready(function(){

     //your code here
 });

This should solve your problem.

Besides this, to further enhance performance you can bind the event to a top level element say a UL instead of each LI. This would help you extract better performance too. Since you are using jQuery 1.4.2, you can easily use jQuery delegate for this.

Feel free to clarify any doubts.

Thanks,
Pranav Kaushik

pranavkaushik.wordpress.com

Pranav Kaushik