psj01
psj01

Reputation: 3245

addClass after animate not working with jquery

addClass after animate not working properly with jquery.

When I click on a button I am trying to bring the banner from the bottom up and when the user clicks again, it will go back to the bottom and hide away.

below is the code I have so far. The first part works, but the second part it doesn't slide down.. simply goes away instead.

Any help is appreciated.

Thanks!

$(document).ready(function() {

  $("#projs").click(function() {
    if ($("#projList").hasClass('hideAway')) {
      $("#projList").removeClass('hideAway').animate({
        bottom: '25%'
      });
    } else {
      $("#projList").animate({
        bottom: '0'
      }).addClass('hideAway'); //.addClass('hideAway');
    }

  });


});
.hideAway {
  visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" id="projs" value="Some Projects" style="border:none;border: 2px solid #e7e7e7;"></input>
<div id="projList" style="width:100%;position:absolute;bottom:0;" class="hideAway">
  <table style="margin:0px;width:100%;padding:0px;">
    <tr>
      <td bgcolor="#EA664A" align="center" height="75" width="75">
      </td>
      <td bgcolor="#D8B90C" align="center" height="75" width="75">
      </td>
    </tr>
    <tr>
      <td bgcolor="#0CD836" align="center" height="75" width="75">
      </td>
      <td bgcolor="#1AD8E3" align="center" height="75" width="75">
      </td>
    </tr>
  </table>
</div>

jsfiddle link

Upvotes: 4

Views: 1958

Answers (5)

Ehsan
Ehsan

Reputation: 12969

You must add class after finish animation.

$("#projList").animate({bottom:'0%'},function(){$(this).addClass('hideAway')})

$(document).ready(function(){
  $("#projs").click(function(){
    if($("#projList").hasClass('hideAway')) 
      $("#projList").removeClass('hideAway').animate({bottom: '20%'});
    else
      $("#projList").animate({bottom:'0%'},function(){$(this).addClass('hideAway')})
  });
});
.hideAway {
    visibility:hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<input type="button" id="projs" value="Some Projects" style="border:none;border: 2px solid #e7e7e7;"></input>
<div id="projList" style="width:100%;position:absolute;bottom:0;" class="hideAway"> 
  <table style="margin:0px;width:100%;padding:0px;">
    <tr>
      <td bgcolor="#EA664A" align="center" height="75" width="75"></td>
      <td bgcolor="#D8B90C" align="center" height="75" width="75"></td>
    </tr>
    <tr>
      <td bgcolor="#0CD836" align="center" height="75" width="75"></td>
      <td bgcolor="#1AD8E3" align="center" height="75" width="75"></td>
    </tr>
  </table>    
</div>

Note: Use of Full page for see result.

Upvotes: 2

yqlim
yqlim

Reputation: 7098

It doesn't work as expected because the functions chained behind doesn't wait before executing. They are all executed together and do not waiting until previous function finish executing.

You can utilise the callback function in .animate.

The last parameter of jQuery's .animate is the callback function.

A callback function will execute after the parent function has finished its execution.

jsFiddle here.

$(document).ready(function() {

  $("#projs").click(function() {
    if ($("#projList").hasClass('hideAway')) {
      $("#projList").removeClass('hideAway').animate({
        bottom: '25%'
      });
    } else {
      $("#projList").animate({bottom: '0'}, function(){
        $(this).addClass('hideAway');
      });
    }

  });


});
.hideAway {
  visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" id="projs" value="Some Projects" style="border:none;border: 2px solid #e7e7e7;"></input>
<div id="projList" style="width:100%;position:absolute;bottom:0;" class="hideAway">
  <table style="margin:0px;width:100%;padding:0px;">
    <tr>
      <td bgcolor="#EA664A" align="center" height="75" width="75">
      </td>
      <td bgcolor="#D8B90C" align="center" height="75" width="75">
      </td>
    </tr>
    <tr>
      <td bgcolor="#0CD836" align="center" height="75" width="75">
      </td>
      <td bgcolor="#1AD8E3" align="center" height="75" width="75">
      </td>
    </tr>
  </table>
</div>

Upvotes: 0

Kakashi Hatake
Kakashi Hatake

Reputation: 3056

You could minimize your code by implementing below:

$(document).ready(function() {
  $("#projs").click(function() {
    $("#projList").slideToggle().css("bottom", "25%").toggleClass("hideAway");
  });
});
.hideAway {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" id="projs" value="Some Projects" style="border:none;border: 2px solid #e7e7e7;"></input>
<div id="projList" style="width:100%;position:absolute;bottom:0;" class="hideAway">
  <table style="margin:0px;width:100%;padding:0px;">
    <tr>
      <td bgcolor="#EA664A" align="center" height="75" width="75">
      </td>
      <td bgcolor="#D8B90C" align="center" height="75" width="75">
      </td>
    </tr>
    <tr>
      <td bgcolor="#0CD836" align="center" height="75" width="75">
      </td>
      <td bgcolor="#1AD8E3" align="center" height="75" width="75">
      </td>
    </tr>
  </table>
</div>

Upvotes: 0

gjijo
gjijo

Reputation: 1206

you can use the call back function of animate for this purpose

	$(document).ready(function() {
	  $("#projs").click(function() {
	    if ($("#projList").hasClass('hideAway')) {
	      $("#projList").removeClass('hideAway').animate({
	        bottom: '25%'
	      });
	    } 
      else {
	      $('#projList').animate({
	        bottom: "0%"
	      }, 800, function() {
	        $(this).addClass('hideAway');
	      });
	    }
	  });
	});
.hideAway {
    visibility:hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="button" id="projs" value="Some Projects" style="border:none;border: 2px solid #e7e7e7;"></input>
<div id="projList" style="width:100%;position:absolute;bottom:0;" class="hideAway">
  <table style="margin:0px;width:100%;padding:0px;">
    <tr>
      <td bgcolor="#EA664A" align="center" height="75" width="75">
      </td>
      <td bgcolor="#D8B90C" align="center" height="75" width="75">
      </td>
    </tr>
    <tr>
      <td bgcolor="#0CD836" align="center" height="75" width="75">
      </td>
      <td bgcolor="#1AD8E3" align="center" height="75" width="75">
      </td>
    </tr>
  </table>
</div>

Upvotes: 0

Jay S.
Jay S.

Reputation: 1327

It's because even though you chained the events, they don't get executed synchronously. jQuery starts an animation in one "thread" and in the other, sets the hiddenAway class. So the animation is overriden. To get around this, just add a delay.

$(document).ready(function() {

    $("#projs").click(function() {
        if ($("#projList").hasClass('hideAway')) {
            $("#projList").removeClass('hideAway').animate({
                bottom: '25%'
            });
        } else {
            $("#projList").animate({
                bottom: '0'
            })
            setTimeout(function() {
                $("#projList").addClass('hideAway');
            }, 300) //.addClass('hideAway');
        }

    });
});

**EDIT: **

Ehsan's answer is probably more appropriate, so you dont need to know the animation time. His answer works by providing a callback function that jQuery will apply when the animation is complete. Here it is as a full function:

$(document).ready(function() {

    $("#projs").click(function() {
        if ($("#projList").hasClass('hideAway')) {
            $("#projList").removeClass('hideAway').animate({
                bottom: '25%'
            });
        } else {
            $("#projList").animate(
                {
                    bottom: '0'
                },
                function() {
                    $("#projList").addClass('hideAway');
                }
            );
        }

    });

});

Upvotes: 1

Related Questions