Reputation: 1521
I have div with id='mainmenu'. I'm adding CSS3 transition to it by JavaScript after button click (by adding 'transition' to #mainmenu and by creating class .fadein and .fadeout that will be added to the div element). Code:
<div id='mainmenu'></div>
<button id="btn1">Click me1</button>
<button id="btn2">Click me2</button>
#mainmenu {
width:100px;
height:100px;
background:#eee;
-webkit-transition: opacity 1s;
-moz-transition: opacity 1s;
transition: opacity 1s;
}
.fadeout {
opacity:0;
}
.fadein {
opacity:1;
}
var menu = document.getElementById('mainmenu'),
btn1 = document.getElementById('btn1'),
btn2 = document.getElementById('btn2');
btn1.addEventListener('click', function() {
menu.className = 'fadeout';
}
btn2.addEventListener('click', function() {
menu.className = 'fadein';
}
The problem is that now I want to add display none and block to fadeout and fadein option. So after the fadeout animation div should get display none, and after fadein display block:
btn1.addEventListener('click', function() {
menu.className = 'fadeout';
menu.style.display = 'none';
}
btn2.addEventListener('click', function() {
menu.className = 'fadein';
menu.style.display = 'block';
}
Unfortunately, the display none and block executes with the animation, so the animation isn't working (element gets display none, without the opacity animation). I want first the animation with opacity, and after that display none/block for the element. Is there any way to do it? I can use only pure JavaScript (no jQuery etc.).
Upvotes: 27
Views: 52456
Reputation: 312
Although this is an old post, for future visitor's sake, you can use the transitionend event. You can use:
/*For when object has fully faded*/
menu.addEventListener("transitionend", function() {
if (this.className == "fadeout") {
this.style.display = "none";
}
}.bind(menu));
/*Show before animation starts*/
menu.addEventListener("click", function() {
this.style.display = "block";
}.bind(menu));
Upvotes: 13
Reputation: 5378
You need to use setTimeout()
with menu.style.display = "none";
in order to let fade do it's job before you trigger style.display
.
btn1.addEventListener('click', function() {
menu.className = 'fadeout';
setTimeout(function() {
$(menu).css('display', 'none');
}, 1000);
}
btn2.addEventListener('click', function() {
menu.className = 'fadein';
setTimeout(function() {
$(menu).css('display', 'block');
}, 1000);
}
Upvotes: 17
Reputation: 447
I use height 0 instead of display none for some cases but It may or may not apply for what you need. Anyway here's the code:
1) Using transitions (looks like jQuerys fadeOut):
.fadeOut{
opacity : 0;
height : 0;
transition : opacity 800ms, height 0 800ms;
}
if you want you can add width 0 too.
.fadeOut{
opacity : 0;
width : 0;
height : 0;
transition : opacity 800ms, height 0 800ms, width 0 800ms;
}
2) Using animations (it works but transitions is better):
.fadeOut{
animation : fadeout 800ms linear forwards;
}
@keyframes fadeout{
99%{
opacity : 0;
height : initial;
}
100%{
opacity : 0;
height : 0;
}
}
Upvotes: 8
Reputation: 386
I could be wrong here, however i believe you need to add a transition-end trigger that does the display:block / display:none change.
Upvotes: 10