Joe Morano
Joe Morano

Reputation: 1895

Mouseenter / Mouseleave creates flickering effect

I have a black icon which I would like to turn blue while the cursor is hovering over it. It does turn blue if I keep the cursor still, but if I move it around, the icon starts flickering blue and black. I made a jfiddle to illustrate:

http://jsfiddle.net/8t2whdop/3/

And here's the code in my view:

<%= image_tag("IconBlack.png", class: "link", id: "icon-black") %>
<%= image_tag("IconBlue.png", class: "link", id: "icon-blue") %>
<script type="text/javascript">
  $('#icon-blue').hide();
  $('#icon-black').mouseenter(function () {
    $('#icon-black').hide();
    $('#icon-blue').show();
  });
  $('#icon-black').mouseleave(function () {
    $('#icon-black').show();
    $('#icon-blue').hide();
  });
</script>

Apparently this is a common problem with mouseenter/leave considering the number of similar questions. This isn't a duplicate however, because I tried all the solutions that I found, and none of them fixed my particular problem. For example, I tried all different combinations of mouseover/out/enter/leave/toggle/hover. How can I stop the flickering effect?

Upvotes: 2

Views: 2399

Answers (3)

Armel Larcier
Armel Larcier

Reputation: 16027

First, you could do this with CSS only, no JS needed :

http://jsfiddle.net/8t2whdop/7/

HTML

<div id="icon">
</div>

CSS

#icon{
    height: 60px;
    width: 60px;
    background: black;
}
#icon:hover{
    background: blue;
}

Then I'll explain why your code is giving this result (expected):

When you hover the black icon, you call jQuery hide method on it which is setting display: none; on the black icon (after a few milliseconds) thus triggering the mouseleave event. So it instantly shows the black icon again which triggers the mouseenter event and so on...

If you wan't (or need) to do it with JS, you could use a wrapper div to catch events (but even so, using two different divs for each background is not efficient):

HTML

<div id="icon">
    <div id="icon-black"></div>
    <div id="icon-blue"></div>
</div>

JS

$('#icon-blue').hide();
$('#icon').mouseenter(function () {
  $('#icon-black').hide();
  $('#icon-blue').show();
});
$('#icon').mouseleave(function () {
  $('#icon-black').show();
  $('#icon-blue').hide();
});

See fiddle :

http://jsfiddle.net/8t2whdop/6/

Upvotes: 3

Louie Almeda
Louie Almeda

Reputation: 5612

I think this will be better solved using css, if you just want the color to be changed on hover

#icon{
    height: 60px;
    width: 60px;
    background-color: black;
}

#icon:hover{
    background-color: blue;
}

If you need to change the image of the box:

#icon{
    height: 60px;
    width: 60px;
    background-image: url("IconBlack.png");
}

#icon:hover{
    background-image: url("IconBlue.png");

}

Upvotes: 0

Roko C. Buljan
Roko C. Buljan

Reputation: 206151

by simply using the right selector $('#icon-blue').mouseleave demo

$('#icon-blue').hide();
$('#icon-black').mouseenter(function () {
  $('#icon-black').hide();
  $('#icon-blue').show();
});
$('#icon-blue').mouseleave(function () { // the #icon blue!!!
  $('#icon-black').show();
  $('#icon-blue').hide();
});

Also note that what you need can be done in pure CSS

In either cases it's easier to write JS and CSS for such things if you wrap your icons inside a common parent element -- cause than, all you need is to target :hover or in jQ .hover() that parent.

Upvotes: 4

Related Questions