1

I have an event handler bound to the hover event using the .hover method, which is below:

$(".nav li").hover(function () {
    $(this).addClass("hover");
}, function () {
    $(this).removeClass("hover");
});

It is important to note, that I require both functions within the handler to ensure synchronisation. Is it possible to rewrite the function using .delegate, as the following does not work?

$(".nav").delegate("li", "hover", function () {
    $(this).addClass("hover");
}, function () {
    $(this).removeClass("hover");
});

Rich

kim3er
  • 6,306
  • 4
  • 41
  • 69

2 Answers2

2

Try this approach:

$(".nav").delegate("li", "hover", function () {
    $(this).toggleClass("hover");
});

This depends on .nav not getting replaced via AJAX or otherwise though, since that's where the event handler lives. If it is being replaced, you have to attach the delegate on a higher ancestor that's not getting replaced.

Also a minor correction, $(".nav li").hover(function () { isn't using the .live() method, that would be: $(".nav li").live('hover', function () {. .hover() binds the event directly to the element when that code runs...any future elements wouldn't trigger that hover code, that's where .live() and .delegate() differ, they work on future elements via bubbling.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • Very embarrassed. Blindly assumed I was converting a .live method instead of a .hover method, eyes evidently not focusing properly today. So +1 for that. With respect to attaching to a parent that is at risk of being programmatically replaced. I hadn't realised the restriction and have been attaching to parents that don't necessarily exist at the time of binding with no problem. – kim3er Apr 07 '10 at 11:47
  • @kim3er - With your current method, they must exist at the time of the binding, otherwise the selector would find/bind nothing :) If your current method works, the delegate method I posted should as well, give it a shot, let me know if you have other problems. – Nick Craver Apr 07 '10 at 11:51
  • Sorry, I was referring to the .delegate method, not .hover in that last sentence. – kim3er Apr 07 '10 at 12:00
  • And again you are correct. .delegate methods need to be attached to a static element, which makes perfect sense when you think about it. Thanks for all your help. – kim3er Apr 07 '10 at 12:05
  • With respect to the original question. I will be keeping the .hover method as there doesn't appear to be a direct replacement using .delegate at the moment. – kim3er Apr 07 '10 at 12:07
  • @kim3er - Correct, there's no direct replacement, and if it works no reason breaking it :) – Nick Craver Apr 07 '10 at 12:13
1

To add/remove a class Nick's solution is perfect as jQuery provides the appropriate toggleClass method.

If you need to trigger more complex functions that do not have a corresponding toggle method available, you can do that by testing the event type:

$(".nav").delegate("li", "hover", function (event) {
if(event.type == "mouseenter"){
    $(this).find(".subDiv").slideDown();
}else{
    $(this).find(".subDiv").slideUp();
}
});

This will work for jQuery >=1.4.3 - for older versions use mouseover instead of mouseenter.

Jpsy
  • 20,077
  • 7
  • 118
  • 115