Keaire
Keaire

Reputation: 899

FadeOut one element and fadeIn another element on hover

I'm trying to achieve an effect where on the hover of an element A, an element B is fadeOut and an element C is fadeIn, both inside the element A.

That's what I tried:

$('.button').hover(function() {
	info = $(this).find('.info');
	download = $(this).find('.download');

	info.stop().fadeOut(150, function() {
		download.stop().fadeIn(150);
	})
}, function() {
	download.stop().fadeOut(150, function() {
		info.stop().fadeIn(150);
	})
})
.button {
  background-color: orange;
  padding: 10px;
  width: 250px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  margin-bottom: 10px;
}

.download {
  display: none;
  font-size: 17px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="button">
  <div class="info">
    <i class="fas fa-download"></i> <strong>Mega Limited</strong> 1GB
  </div>
  <div class="download">Download</div>
</div>

<div class="button">
  <div class="info">
    <i class="fas fa-download"></i> <strong>Mega Limited</strong> 1GB
  </div>
  <div class="download">Download</div>
</div>

<div class="button">
  <div class="info">
    <i class="fas fa-download"></i> <strong>Mega Limited</strong> 1GB
  </div>
  <div class="download">Download</div>
</div>

<div class="button">
  <div class="info">
    <i class="fas fa-download"></i> <strong>Mega Limited</strong> 1GB
  </div>
  <div class="download">Download</div>
</div>

Hovering one element at a time seems working fine but when you try to hover more elements concurrently the animation it starts to break.

Any solution? Other approaches are accepted. Thanks.

Upvotes: 1

Views: 41

Answers (2)

skyline3000
skyline3000

Reputation: 7913

You are inadvertently creating global variables for info and download by omitting the var, let, or const keywords. That means every function call is using and overwriting those variables. You need to create local variables in each function.

$('.button').hover(function() {
  var info = $(this).find('.info');
  var download = $(this).find('.download');

  download.stop();
  info.stop().fadeOut(150, function() {
    download.stop().fadeIn(150);
  })
}, function() {
  var info = $(this).find('.info');
  var download = $(this).find('.download');

  info.stop();
  download.stop().fadeOut(150, function() {
    info.stop().fadeIn(150);
  })
})
.button {
  background-color: orange;
  padding: 10px;
  width: 250px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  margin-bottom: 10px;
}

.download {
  display: none;
  font-size: 17px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="button">
  <div class="info">
    <i class="fas fa-download"></i> <strong>Mega Limited</strong> 1GB
  </div>
  <div class="download">Download</div>
</div>

<div class="button">
  <div class="info">
    <i class="fas fa-download"></i> <strong>Mega Limited</strong> 1GB
  </div>
  <div class="download">Download</div>
</div>

<div class="button">
  <div class="info">
    <i class="fas fa-download"></i> <strong>Mega Limited</strong> 1GB
  </div>
  <div class="download">Download</div>
</div>

<div class="button">
  <div class="info">
    <i class="fas fa-download"></i> <strong>Mega Limited</strong> 1GB
  </div>
  <div class="download">Download</div>
</div>

Upvotes: 1

skobaljic
skobaljic

Reputation: 9614

The main problem is to stop the animation before assigning another. This way there are no glitches:

$('.button').each(function(i) {
    var thisButton = $(this);
    var thisInfo = thisButton.find('.info');
    var thisDownload = thisButton.find('.download');
    thisButton.on('mouseenter', function(e) {
        thisDownload.stop();
        thisInfo.stop().fadeOut(150, function() {
            thisDownload.stop().fadeIn(150);
        });
    }).on('mouseleave', function(e) {
        thisInfo.stop();
        thisDownload.stop().fadeOut(150, function() {
            thisInfo.stop().fadeIn(150);
        });
    });
});
.button {
  background-color: orange;
  padding: 10px;
  width: 250px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  margin-bottom: 10px;
}

.download {
  display: none;
  font-size: 17px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="button">
    <div class="button_inner">
        <div class="info">
            <i class="fas fa-download"></i> <strong>Mega Limited</strong> 1GB
        </div>
        <div class="download">Download</div>
    </div>
</div>

<div class="button">
    <div class="button_inner">
        <div class="info">
            <i class="fas fa-download"></i> <strong>Mega Limited</strong> 1GB
        </div>
        <div class="download">Download</div>
    </div>
</div>

<div class="button">
    <div class="button_inner">
        <div class="info">
            <i class="fas fa-download"></i> <strong>Mega Limited</strong> 1GB
        </div>
        <div class="download">Download</div>
    </div>
</div>

Also on JSFiddle

Posting this because this may happen to skyline's answer:

enter image description here

Upvotes: 2

Related Questions