drake035
drake035

Reputation: 2897

Flashing when using jQuery mouseenter() and mouseleave()

Following advice from several answers I switched from using hover() to mouseover() to finally mouseenter() and mouseleave(). Yet I STILL get the flashing problem (when hovering the .staff_img image element, the mouseleave() event keeps firing every second. What am I doing wrong?

JS

$('.staff_img').mouseenter(function() {
  $(this).siblings('.staff_hover').fadeIn();
});
$('.staff_img').mouseleave(function() {
  $(this).siblings('.staff_hover').fadeOut();
});

HTML

<img class="staff_img" />
<div class="staff_hover"></div>

CSS

.staff img {
  width: 100%;
  max-width: 100%;
  height: auto;
}
.staff_hover {
  display: none;
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background: rgba(0,0,0,0.6);
}

Upvotes: 0

Views: 97

Answers (3)

frnt
frnt

Reputation: 8795

Your codes works fine, only when you want .staff_hover to appear after .staff_img on mouseenter(), in that case just change the z-index of .staff_hover as in below codes,

$('.staff_img').mouseenter(function() {
  $(this).siblings('.staff_hover').fadeIn();
});
$('.staff_img').mouseleave(function() {
  $(this).siblings('.staff_hover').fadeOut();
});
.staff img {
  width: 100%;
  max-width: 100%;
  height: auto;
}
.staff_hover {
  display: none;
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background: rgba(0,0,0,0.6);
  z-index:-1; /*Add this*/
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img class="staff_img" src="https://lorempixel.com/200/100/"/>
<div class="staff_hover"></div>

And if you want .staff_hover to appear before .staff_image then you need to change your jQuery little bit. Which hides .staff_hover on mouseleave(), as in below codes.

$('.staff_img').mouseenter(function() {
  $(this).siblings('.staff_hover').fadeIn();
});
$('.staff_hover').mouseleave(function() {
  $(this).fadeOut();
});
.staff img {
  width: 100%;
  max-width: 100%;
  height: auto;
}
.staff_hover {
  display: none;
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background: rgba(0,0,0,0.6);
  z-index:9;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img class="staff_img" src="https://lorempixel.com/200/100/"/>
<div class="staff_hover"></div>

Upvotes: 0

sinisake
sinisake

Reputation: 11338

If your intention is that overlay goes above image (i guess, because it is overlay?), one possible solution would be to get position of image, calculate width and height, get mouse/cursor position on mousemove, and do something like this:

    pos=$('.staff_img').position();
    pos_x=pos.left
    pos_y=pos.top

     w=$('.staff_img').width();
     h=$('.staff_img').height();




  $( document ).on( "mousemove", function( event ) {

    if((event.pageX>=pos_x && event.pageX<pos_x+w) && (event.pageY>=pos_y && event.pageY<pos_y+h )) {
    $('.staff_hover').fadeIn();
    }
    else {
    $('.staff_hover').fadeOut();
    }
    });

Demo:

pos=$('.staff_img').position();
pos_x=pos.left
pos_y=pos.top

w=$('.staff_img').width();
h=$('.staff_img').height();


$( document ).on( "mousemove", function( event ) {

if((event.pageX>=pos_x && event.pageX<pos_x+w) && (event.pageY>=pos_y && event.pageY<pos_y+h )) {
$('.staff_hover').fadeIn();
}
else {
$('.staff_hover').fadeOut();
}
});
.staff img {
  width: 100%;
  max-width: 100%;
  height: auto;
}
.staff_hover {
  display: none;
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background: rgba(0,0,0,0.6);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img class="staff_img" src='http://placehold.it/200x200'>
<div class="staff_hover"></div>

But, i guess that your image and overlay have same dimensions, and that both are placed inside some container, so, this is complete unnecesary. Maybe it will help someone, anyway... :)

Upvotes: 0

Temani Afif
Temani Afif

Reputation: 273750

This is due to the fact that the staff_hover div is going on top of the image which trigger the mouseleave on the image, then the div will disappear again and trigger the mousenter, etc. That's why it's flashing.

You may add z-index to staff_hover to make it below the image and avoid this issue :

$('.staff_img').mouseenter(function() {
  $(this).siblings('.staff_hover').fadeIn();
});
$('.staff_img').mouseleave(function() {
  $(this).siblings('.staff_hover').fadeOut();
});
.staff_img {
  width: 100%;
  max-width: 100%;
  height: auto;
}

.staff_hover {
  display: none;
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  z-index:-99;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img class="staff_img" src="https://lorempixel.com/200/100/" />
<div class="staff_hover"></div>

And if you want to cover the image with an overlay you may simply use some CSS transition like this :

.staff_img {
  width: 100%;
  max-width: 100%;
  height: auto;
}

.staff_hover {
  position: relative;
}

.staff_hover:before {
  content:"";
  opacity: 0;
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  transition:1s;
}

.staff_hover:hover::before {
  opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="staff_hover">
  <img class="staff_img" src="https://lorempixel.com/200/100/" />
</div>

Upvotes: 1

Related Questions