Reputation: 3
I'm trying to work out how to fade between css classes triggered by a conditional button click. Instead of a simple class on and class off.
I've adapted the below jsfiddle from this answer to this; mostly working, except for the fade.
// Check if localStorage is supported
if ('localStorage' in window && typeof localStorage == 'object') {
$(document).ready(function() {
// Set the class if greyscale is set
// Note that localStorage saves everything as strings
if (localStorage["darkmode"] == "1") {
$('html').addClass('dark');
$('.daytime').addClass('nighttime').removeClass('daytime');
$("#lightson").val("Turn Lights back on");
}
// Register click listener for the button
$('#lightson').click(function() {
// Toggle greyscale on and off
if (localStorage["darkmode"] != "1") {
$('html').addClass('dark').removeClass('light').fadeIn("fast");
localStorage["darkmode"] = "1";
$('.daytime').addClass('nighttime').removeClass('daytime');
$("#lightson").val("Turn Lights back on");
} else {
$('html').removeClass('dark').addClass('light').fadeIn("fast");
localStorage["darkmode"] = "0";
$('.nighttime').addClass('daytime').removeClass('nighttime');
$("#lightson").val("Dark Mode");
}
}); // - button click
}); // - doc ready
}
html.light {
background: white;
color: grey;
}
html.dark {
background: grey;
color: white;
}
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus egestas libero lectus, ac elementum est euismod sit amet. Sed maximus ac ipsum non pulvinar. Nulla tempor turpis a metus sollicitudin, in interdum dui mollis. Curabitur dictum magna magna,
sit amet tempus justo consequat sit amet. Vestibulum varius nisl justo, vel egestas justo scelerisque sit amet. Duis vulputate lacinia lacus id lacinia. Sed vel tellus id nulla finibus pellentesque vel eu sapien. Praesent risus eros, pellentesque in
tempor a, vestibulum sit amet purus. Mauris sapien velit, varius nec ex eget, vestibulum laoreet diam. Nam eros nisi, euismod ultrices viverra eu, dictum quis nisl. Suspendisse quis eleifend quam. Curabitur consectetur diam non ante rutrum, tincidunt
placerat felis tincidunt. Fusce vitae dolor dui. Morbi mattis eu dui sit amet laoreet.</div>
<input type="button" id="lightson" class="daytime" value="Dark Mode">
You can see the transition is harsh between dark to light and I would like to fade between them some how. I tried appending: .fadeIn("fast");
to the two 'add and removeClass' lines in the above jsfiddle statements like this: $('html').addClass('dark').removeClass('light').fadeIn("fast");
However that seemed to not do anything at all, and probably for a good reason
I cannot solve the issue with plain css in the stylesheet as I don't want the fade in effect each time the page loads, just when the button is pressed.
Upvotes: 0
Views: 435
Reputation: 1844
The 'fadeIn' method in jQuery animates the opacity of a hidden element rather than animating between classes.
Have you considered using css transitions?
html {
background:white;
color:grey;
transition: all 0.4s
}
html.dark {
background: grey;
color: white;
}
Then the only javascript you need is to toggle the 'dark' class on the html element.
The reason you get the fade in when you load the page, is in your original code you are applying the 'dark' class after the page has loaded, which triggers the animation. If you ensure that the HTML tag doesn't have the 'transition' property until after you've set your initial styles you can avoid this unwanted animation.
Here's an example using your original code. Note the extra line:
document.createElement('div').offsetHeight;
This is needed because some browsers won't apply style changes immediately as they try and optimise the number of times they redraw the layout by queueing changes until they have to. This hack forces the browser to apply your styles immediately as it has to make sure it's giving you the correct value.
Upvotes: 2
Reputation: 80
Since this was downvote-worthy, I'll elaborate.
You can't fade in or out a class. Either you have it, or you don't. What you can do is to transition the styles associated with that class. However, the fadeIn / fadeOut functions are not the way to do that:
The fadeIn() method gradually changes the opacity, for selected elements, from hidden to visible (fading effect).
http://www.w3schools.com/jquery/eff_fadein.asp
Maybe this is more what you're looking for. The pertinent bits being the transition property. Example:
Summary of changes:
JS
// Check if localStorage is supported
if ('localStorage' in window && typeof localStorage == 'object') {
$(document).ready(function () {
// Set the class if greyscale is set
// Note that localStorage saves everything as strings
if (localStorage["darkmode"] == "1") {
$('html').addClass('dark');
$('.daytime').addClass('nighttime').removeClass('daytime');
$("#lightson").val("Turn Lights back on");
}
// Register click listener for the button
$('#lightson').click(function () {
// Toggle greyscale on and off
if (localStorage["darkmode"] != "1") {
$('html').addClass('dark');
localStorage["darkmode"] = "1";
$('.daytime').addClass('nighttime').removeClass('daytime');
$("#lightson").val("Turn Lights back on");
} else {
$('html').removeClass('dark');
localStorage["darkmode"] = "0";
$('.nighttime').addClass('daytime').removeClass('nighttime');
$("#lightson").val("Dark Mode");
}
}); // - button click
}); // - doc ready
}
CSS
html {
background:white;
color:grey;
transition: all 0.8s;
}
html.dark {
background: grey;
color: white;
transition: all 0.8s;
}
Upvotes: 1
Reputation: 800
You can use jquery-ui and the .switchClass()
function
$('html').switchClass('light','dark', 1000, 'linear');
and to change back
$('html').switchClass('dark','light', 1000, 'linear');
Alternatively you can use the .toggleClass()
and give the body the default light properties, this would be easy for toggling.
You can also use the jquery .animate()
function, you would need to specify the css within the function however not the class names.
Upvotes: 2
Reputation: 6933
You need jQuery ui to make transitions between classes.
Example here http://jsfiddle.net/v5vw9r3a/6/
$('html').addClass('dark', 1000, "easeOutSine");
Upvotes: 1
Reputation: 18891
I recommend using a CSS3 transition
instead of JS animations:
html{
transition: all 0.5s;
}
Demo: http://jsfiddle.net/v5vw9r3a/4/
However, to answer your asked question, fadeOut
the element, and make the class change and fadeIn
a callback of it, i.e.:
$html = $('html'); // Don't search for the element so many times -- that is slow
$html.fadeOut("fast",function(){ // fadeOut fast, then:
$html.addClass('dark').removeClass('light').fadeIn("fast"); // addClass, removeClass, and fadeIn
});
Demo: http://jsfiddle.net/v5vw9r3a/5/
Upvotes: 1