Reputation: 43
I got this piece of JavaScript and I want to fade in my divs
by changing the class and letting this (new) CSS3 effect animate a fade in. I used .click
and .fadeToogle
before but this lags far too much. CSS3 animation should be much better on the mobile phone if you read all the discussion about the setTimer thing and CSS3 Animations. (I'm doing this as a hybrid app on phonegapp so yes it's really laggy!)
This code works to show my div when clicked but fails to read the new class it gets assigned and doesn't close the div again. Here is the JavaScript/jQuery code:
$(function() {
$("#stylesButtonImg").click(function() {
if ($('#styles').hasClass("closed")) {
$('#styles').removeClass('closed');
$('#styles').addClass('open');
} else if ($('#styles').hasClass("open")) {
$('#styles').removeClass('open');
$('#styles').addClass('close');
}
});
});
#styles {
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
position: absolute;
left: 200px;
height: 100px;
width: 100px;
background-color: rgba(000, 000, 000, 0.95);
transition: 1s opacity;
}
.closed{display:none;}
.open{display:block;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="stylesButtonImg">click me</button>
<div id="styles" class="closed">
<?php include 'styles.php';?>
</div>
Upvotes: 3
Views: 471
Reputation: 26791
Following on @Robert McKee answer.
I will quote the OP comment:
I really can't change away from having it displayed as none because of having a complete dynamic webpage where I don't refresh and every "page" is in the index.php file but diplayed as none so the whole structure doesn't shift because of the space visibility creats...
When forced to use display: none;
what can be done is use an animation
instead.
The .close
and .open
classes will still be used:
.closed {
opacity: 0;
display: none;
}
.open {
display: block;
animation: activePage 1s forwards;
}
Notice how now we use an animation in the .open
class, which purpose is to animate from opacity: 0
to opacity: 1;
, using forwards as a value in the animation-fill-mode
property to keep the styles after the animation
ends:
@keyframes activePage {
to {
opacity: 1;
}
}
Code Snippet:
$(function() {
$("#stylesButtonImg").click(function() {
$('#styles').toggleClass('open', 'closed');
});
});
#styles {
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
position: absolute;
left: 200px;
height: 100px;
width: 100px;
background-color: rgba(000, 000, 000, 0.95);
}
.closed {
opacity: 0;
display: none;
}
.open {
display: block;
animation: activePage 1s forwards;
}
#stylesButtonImg {
position: relative;
z-index: 2
}
@keyframes activePage {
to {
opacity: 1;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="stylesButtonImg">click me</button>
<div id="styles" class="closed">
<?php include 'styles.php';?>
</div>
EDIT:
Because the animation
is removed on .closed
class, when toggling back to close the "view", there will be no animation.
To solve this issue, we might need to take this further with JS.
The solution I will provide may have to be cleaned and/or improved by you, its objective is to guide you in the right direction.
Using the jQuery.fn.extend() method we will toggle between states on click. When the animation is finished it will toggle the classes .open
and .closed
.
The animations will be set with:
@keyframes fadeIn {
0% {
opacity: 0
}
100% {
opacity: 1
}
}
@keyframes fadeOut {
0% {
opacity: 1
}
100% {
opacity: 0
}
}
.fadeIn {
-webkit-animation-name: fadeIn;
animation-name: fadeIn;
}
.fadeOut {
-webkit-animation-name: fadeOut;
animation-name: fadeOut;
}
Code Snippet:
$.fn.extend({
switchView: function() {
var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';
var activeAnimationName = "fadeIn",
inactiveAnimationName = "fadeOut",
activeState = "open",
inactiveState = "closed";
var toggleState = function(el, animationName, currentState) {
var $this = $(el);
$this.removeClass(currentState);
$this.addClass('animated ' + animationName).one(animationEnd, function() {
$this.removeClass('animated ' + animationName);
if (currentState === inactiveState) {
$this.addClass(activeState);
} else {
$this.addClass(inactiveState);
}
});
}
if (this.hasClass(inactiveState)) {
toggleState(this, activeAnimationName, inactiveState);
} else {
toggleState(this, inactiveAnimationName, activeState);
}
}
});
$(function() {
$("#stylesButtonImg").click(function() {
$('#styles').switchView();
});
});
.animated {
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both
}
#styles {
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
position: absolute;
left: 200px;
height: 100px;
width: 100px;
background-color: rgba(000, 000, 000, 0.95);
}
.closed {
display: none;
}
.open {
display: block;
}
#stylesButtonImg {
position: relative;
z-index: 2
}
@keyframes fadeIn {
0% {
opacity: 0
}
100% {
opacity: 1
}
}
@keyframes fadeOut {
0% {
opacity: 1
}
100% {
opacity: 0
}
}
.fadeIn {
-webkit-animation-name: fadeIn;
animation-name: fadeIn;
}
.fadeOut {
-webkit-animation-name: fadeOut;
animation-name: fadeOut;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="stylesButtonImg">click me</button>
<div id="styles" class="closed">
<?php include 'styles.php';?>
</div>
Upvotes: 1
Reputation: 43
Update!
I didn't make it work with the display property on none but I changed it to the visibility property. As the comments pointed out were the elements assignd to a absolute position which takes the elements(div's) out of he usual order. I then added the overflow:hidden property to hide the scrollbars and the invisible space which i thought was there but never was.
This is the code I use for now:
.closed{
overflow: hidden;
opacity: 0;
visibility: hidden;
}
.open{
overflow: hidden;
opacity: 1;
visibility:visible;
}
#styles{
transition: .20s linear;
left:0px;
right:0px;
top:0px;
bottom:0px;
position:absolute;
height:100vh;
width:100vw;
background-color: rgba(000, 000, 000, 0.95);
}
I got this html code for my picture buttons which work as toggles:
<div id="styles" class="closed">
<?php include 'styles.php';?>
</div>
And this is my javascript which changes the classes so no unececery javascript is execudet and the css, which is supportet by mobile phones hardware acceleration, works much faster and consistent this way.
$(document).ready(function() {
$(function() {
$("#stylesButtonImg").click(function() {
//The div which gets shown.
$('#styles').toggleClass('open', 'closed');
//All my other buttons who get faded out if they are active when i want to open the, in this case, styles page.
$('#rateableUserProfile').removeClass('open').addClass('closed');
$('#profile').removeClass('open').addClass('closed');
$('#options').removeClass('open').addClass('closed');
$('#savedStyles').removeClass('open').addClass('closed');
$('#camera').removeClass('open').addClass('closed');
});
});
});
Upvotes: 0
Reputation: 3907
Fading in and out through css is done by opacity
. Your css seems to be wrong at the point where you're defining display: none;
and display: block;
. You may change those options through opacity: 1;
and opacity: 0;
Your css should like that:
#styles {
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
position: absolute;
left: 200px;
height: 100px;
width: 100px;
background-color: rgba(0, 0, 0, 1);
transition: 1s opacity;
}
.closed {
// display: none;
opacity: 0;
}
.open {
opacity: 1;
}
You can also clean up your whole JS code with just a single line inside of your click function.
$("#stylesButtonImg").click(function() {
$('#styles').toggleClass('closed', 'open');
});
Upvotes: 0
Reputation: 21477
Don't use display:none, as that can't be animated. Use opacity instead, which is animatable. Also, toggleClass will flip between open/closed for you rather than you having to check and flip yourself.
$(function() {
$("#stylesButtonImg").click(function() {
$('#styles').toggleClass('open', 'closed');
});
});
#styles {
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
position: absolute;
left: 200px;
height: 100px;
width: 100px;
background-color: rgba(000, 000, 000, 0.95);
transition: 1s opacity;
}
.closed {
opacity: 0;
}
.open {
opacity: 1;
}
#stylesButtonImg {
position: relative;
z-index: 2
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="stylesButtonImg">click me</button>
<div id="styles" class="closed">
<?php include 'styles.php';?>
</div>
Upvotes: 3
Reputation: 1447
I would actually suggest using
$(function() {
$("#stylesButtonImg").click(function() {
if ($('#styles').is(":visible")) {
$('#styles').hide(time);
} else {
$('#styles').show(time);
}
});
});
where time
is the amount of time you want the hide/show animation to take in milliseconds (0 if you don't want animation). You also don't need the css if you do this.
Might as well use all of jquery's power if you're gonna use it.
Upvotes: 1