Bartek W
Bartek W

Reputation: 27

The opacity change animation in jQuery is not working

I have an issue with the jQuery animation. I have an element that should:
(1) change its opacity from 0 to 1 and slide down in the same time
(2) and then shrink from 100% height to 5px height when is mouse over its parent and go back when the mouse is out of the parent.
Everything works except the very first animation which is opacity change. Why is that? What am I doing wrong?
Here's my code:

var $menu_it = jQuery('.menu-item');
$menu_it.append('<span class="menu_item_bar"></span>');
$menu_it.mouseover(function(){
    jQuery(this).find('.menu_item_bar').stop(true,true).animate({"opacity":"1"}, 100);
    jQuery(this).find('.menu_item_bar').stop(true,true).animate({"bottom":"25px"}, 100);
    jQuery(this).find('.menu_item_bar').stop(true,true).delay(100).animate({"height":"5px"}, 500);
});
$menu_it.mouseout(function(){
    jQuery(this).find('.menu_item_bar').stop(true,true).animate({"height":"100%"}, 500, function(){
        jQuery(this).stop(true,true).animate({"opacity":"0"}, 500);
    });
    jQuery(this).find('.menu_item_bar').stop(true,true).animate({"bottom":"190px"}, 750);
});

And here's jsfiddle:
https://jsfiddle.net/sg5db8y1/21/
Thank you in advance for yor help.
PS There's jQuery instead of $ sign cause I have to do this in Wordpress enviroment.

Upvotes: 1

Views: 480

Answers (1)

Rory McCrossan
Rory McCrossan

Reputation: 337560

The problem is because you repeatedly call stop(true, true) as you define each animation. This means that you're ending the previously defined animation (which only just started) and move it to its final position.

To fix this, don't call stop() when defining successive animations, or better still, define all animations in the same call:

var $menu_it = $('.menu-item');
$menu_it.append('<span class="menu_item_bar"></span>');

$menu_it.mouseover(function() {
  $(this).find('.menu_item_bar').stop(true, true).animate({
    "opacity": "1",
    "bottom": "25px",
    "height": "5px"
  }, 500);
});

$menu_it.mouseout(function() {
  $(this).find('.menu_item_bar').stop(true, true).animate({
    "height": "100%",
    "opacity": "0",
    "bottom": "190px"
  }, 750);
});
body .menu-item {
  padding: 50px 25px 0 25px;
  position: relative;
  display: inline-block;
}

.menu-item a {
  padding-bottom: 86px;
  text-decoration: none;
  color: #111;
}

.menu_item_bar {
  width: 100%;
  position: absolute;
  height: 100%;
  bottom: 100px;
  left: 0;
  z-index: 9999;
  opacity: 0;
  background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="menu-item">
  <a href="#">Menu item 1</a>
</div>
<div class="menu-item">
  <a href="#">Menu item 2</a>
</div>
<div class="menu-item">
  <a href="#">Menu item 3</a>
</div>

That being said, you can make this much more effectively using CSS only:

body .menu-item {
  padding: 50px 25px 0 25px;
  position: relative;
  display: inline-block;
}

.menu-item a {
  padding-bottom: 86px;
  text-decoration: none;
  color: #111;
}

.menu-item:hover .menu_item_bar {
  opacity: 1;
  height: 5px;
  bottom: 25px;
}

.menu_item_bar {
  width: 100%;
  position: absolute;
  height: 100%;
  bottom: 100px;
  left: 0;
  z-index: 9999;
  opacity: 0;
  background: red;
  transition: opacity 0.5s, bottom 0.5s, height 0.5s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="menu-item">
  <a href="#">Menu item 1</a>
  <span class="menu_item_bar"></span>
</div>
<div class="menu-item">
  <a href="#">Menu item 2</a>
  <span class="menu_item_bar"></span>
</div>
<div class="menu-item">
  <a href="#">Menu item 3</a>
  <span class="menu_item_bar"></span>
</div>

Upvotes: 1

Related Questions