Reputation: 3245
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>
Upvotes: 4
Views: 1958
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
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.
$(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
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
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
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