Thursday, April 14, 2011

jQuery mouseover issues

Hey everyone,

I have image, and on mouse over it fades in two arrows (on the left and right sides), then on mouseout it fades those arrows out. My problem is that when the user hovers over the arrows, the image considers it a mouseout (since the arrows float above the image), and fades the arrows out, causing an infinate loop of fading in/out until you move the mouse away. What is the best way to prevent the arrows from fading out when the mouse hovers over them? I've tried one method, which you'll see below, but that hasen't been working out...

Here's some code:

$(".arrow").mouseover(function() {
 overArrow = 1;
 $("#debug_oar").text(1)
})

$(".arrow").mouseout(function() { 
 overArrow = 0;
 $("#debug_oar").text(0)
})

$("#image").mouseout(function() {
 $(".arrow").fadeOut(250,function() { $(".arrow").remove();})
})

$("#image").mouseover(function() {
 if(overArrow == 0) {
  $("#image").after("<div class='arrow' id='lArrow' style='display:none;position:absolute;'>&larr;</div><div class='arrow' id='rArrow' style='display:none;position:absolute;'>&rarr;</div>")
  // Define variables...
  aWidth = $("#lArrow").width();
  aHeight = $("#lArrow").height();
  height = $("#image").height()
  width = $("#image").width()
  pos = $("#image").position();
  // Calculate positioning
  nHeight = height/2
  y = pos.top + nHeight - (aHeight/2)
  // Position the left arrow
  $("#lArrow").css("top",y)
  $("#lArrow").css("left",pos.left+10)
  // Now the right...
  $("#rArrow").css("top",y)
  $("#rArrow").css("left",pos.left+width-aWidth-20)
  // Display 'em
  $(".arrow").fadeIn(250);
  // Debug info
  $("#debug_x").text(pos.left)
  $("#debug_y").text(y)
  $("#debug_height").text(height)
 }
})

Thanks

For those who are interested in the final code:

$("#image").mouseenter(function() {
 $("#image").append("<div class='arrow' id='lArrow' style='display:none;position:absolute;'>&larr;</div><div class='arrow' id='rArrow' style='display:none;position:absolute;'>&rarr;</div>")
 // Define variables...
 aWidth = $("#lArrow").width();
 aHeight = $("#lArrow").height();
 height = $("#image").height()
 width = $("#image").width()
 pos = $("#image").position();
 // Calculate positioning
 nHeight = height/2
 y = pos.top + nHeight - (aHeight/2)
 // Position the left arrow
 $("#lArrow").css("top",y)
 $("#lArrow").css("left",pos.left+10)
 // Now the right...
 $("#rArrow").css("top",y)
 $("#rArrow").css("left",pos.left+width-aWidth-20)
 // Display 'em
 $(".arrow").fadeIn(250);
 // Debug info
 $("#debug_x").text(pos.left)
 $("#debug_y").text(y)
 $("#debug_height").text(height)
});
$("#image").mouseleave(function() {
 $(".arrow").fadeOut(250,function() { $(".arrow").remove();})
})
From stackoverflow
  • Try to call stopPropagation() on your events, or use an alternative event that stops propagation by default like, mouseenter, mouseleave or hover(over, out).

    Vestonian : This worked, I made it so the image was surrounded by a div, then the arrows were appended to the content on the div, then I used mouseneter and mouseleave. Thanks!
  • The arrows probably aren't children of the image, so hovering them is leaving the image.

    You want to wrap the image and the arrows with a wrapper element, and put the hover() call on that element instead. That way hovering over either the image or arrows triggers it.

    Alternately, learn how to use event delegation. Attach hover() to a higher up element that happens to encompass them both, and then check the target of the hover every time. If it matches either the image or the arrows, trigger the appropriate animation on the arrows.

    This is a good tutorial explaining event delegation in jQuery and how to use it.

    Finally, just for simplicity, use hover() rather than mouseover()/mouseout(). It captures your intent much more clearly. The first function you pass to hover() gets applied on mouseover, the second gets applied on mouseout.

  • Probably the simplest solution would be to put the fade-out transition handler on body and the fade-in as you have it now.

    This way the mouseout event that you're getting wont cause anything to happen, and only when you mouse away from the whole area will it fade out.

0 comments:

Post a Comment