How to stop light mode flickering to darker background on page load - javascript

So I have a bit of script for toggling between light and dark modes on my site. The dark mode is the default. Problem is, whenever the light mode is toggled on, with every page load it flickers to the dark mode for just a second before loading the light mode. I would really like it to not do this and super appreciate any help you all can give. Thanks in advance!
My Code is as follows:
if (localStorage['blackout']) {
if (Number(localStorage['blackout']) == 1) {
$('BODY').addClass('blackout');
} else {
$('BODY').removeClass('blackout');
}
} else {
localStorage['blackout'] = 0;
$('BODY').removeClass('blackout');
}
$('BODY').show();
$('#boToggle').on('click', function(){
if (Number(localStorage['blackout']) == 0) {
localStorage['blackout'] = 1;
$('BODY').addClass('blackout');
} else {
localStorage['blackout'] = 0;
$('BODY').removeClass('blackout');
}
});

Put your JS (the part reading from local storage and applying the class) in the <head> section, and add the class to the <html> tag, so that it get executed before the body is parsed and displayed.
You can try it with this simple working demo:
<html>
<head>
<script>
// Do this before the body gets parsed
if (localStorage.getItem('darkmode') === '1') {
document.documentElement.classList.add('darkmode');
}
</script>
<style>
.darkmode body { background: #222; }
.darkmode .light-only { display: none; }
html:not(.darkmode) .dark-only { display: none; }
</style>
</head>
<body>
<button id="darkToggle">
Switch to
<span class="dark-only">light</span>
<span class="light-only">dark</span>
mode
</button>
<script>
document.querySelector('#darkToggle').addEventListener('click', function() {
var wasDarkMode = localStorage.getItem('darkmode') === '1';
localStorage.setItem('darkmode', wasDarkMode ? '0' : '1');
document.documentElement.classList[wasDarkMode ? 'remove' : 'add']('darkmode');
});
</script>
</body>
</html>

Related

JavaScript Toggle class

'use strict'
const switcher = document.querySelector('.btn');
console.log(switcher);
switcher.addEventListener('click', function() {
document.body.classList.toggle('dark-theme');
let className = document.body.className;
if (className == "light-theme") {
this.textContent = "Dark";
}
else {
this.textContent = "Light";
}
});
Not sure how the toggle works. How is when I click the button the background changes back to the light-theme when the script doesn't even specify to change back to light-theme?
It's the document.body.classList.toggle('dark-theme');.
If that class exists, it is removed. If that class doesn't exist, it is added.
Your button changes the HTML from
<body class="light-theme">
to
<body class="light-theme dark-theme">
and back again.
Using CSS rules, if two rulesets with the same specificity are declared, and one is declared below the other, the one below will take precedence if both apply to an element. So
.light-theme {
/* rules */
}
.dark-theme {
/* rules */
}
will mean that if an element has dark-theme and light-theme, dark-theme's rules will override any duplicate styles applied by light-theme.
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Theme</title>
</head>
<body class="light-theme">
<div>
<button type="button" class="btn">Dark</button>
</div>
<script type="text/javascript">
'use strict'
const switcher = document.querySelector('.btn');
console.log(switcher);
switcher.addEventListener('click', function() {
document.body.classList.toggle('dark-theme');
document.body.classList.toggle('light-theme');
let className = document.body.className;
if (className == "light-theme") {
this.textContent = "Dark";
}
else {
this.textContent = "Light";
}
});
</script>
</body>
</html>

CSS Toggle Switch to add a class to a DIV with local storage

I'm trying to create a simple toggle switch to add a new class to the body tag. By default the page is red. By clicking the button the page is toggled between red and blue.
Here's the code I have so far - the Switch Colour button would then change the body class tag to blue
<body>
<p>Click the button to change the colour of page</p>
<button onclick="myFunction()">Change background colour</button>
<script>
function myFunction() {
var element = document.body;
element.classList.toggle("blue");
}
</script>
</body>
The CSS bit
body {
background-color: red;
color: white;
}
body.blue {
background-color: blue;
}
The bit I'm struggling with is to keep the settings when I refresh the page or move to another page. Is there a way to store this via Local Storage and javascript?
Thanks in advance,
Brian
For a more dynamic solution (what happens if you have more than two colors?), I would instead go with a CSS variable, where the default color is red. Stack Overflow doesn't allow reading from localStorage, so I will comment out that code, and instead use a variable for demo purposes.
I do think the code is self-explanatory.
const BACKGROUND_KEY = 'background';
var forDemoPurposeOnly = '';
function myFunction() {
let isBlue = readFromLocalStorage(BACKGROUND_KEY) == 'blue';
let color = (isBlue) ? 'red' : 'blue';
setBackgroundColor(color);
}
function setBackgroundColor(color) {
let root = document.documentElement;
root.style.setProperty('--user-selected-background', color);
setInLocalStorage(BACKGROUND_KEY, color);
}
function readFromLocalStorage(key) {
return forDemoPurposeOnly;
// return localStorage.getItem(key);
}
function setInLocalStorage(key, value) {
forDemoPurposeOnly = value;
// localStorage.setItem(key, value);
}
:root {
--background-color: var(--user-selected-background, red); /* defaults to 'red' */
}
body {
background-color: var(--background-color);
}
<body onload="setBackgroundColor(readFromLocalStorage('background'))">
<p>Click the button to change the colour of page</p>
<button onclick="myFunction()">Change background colour</button>
</body>
The local storage API is super simple to use. localStorage is available as a global in the browser, you can store a string value with a key and then retrieve the value with the key.
function myFunction() {
var element = document.body;
element.classList.toggle("blue");
var background = localStorage.getItem('background')
if (background === 'blue') {
localStorage.setItem('background', 'red')
} else {
localStorage.setItem('background', 'blue')
}
}
(function() {
var background = localStorage.getItem('background')
if (background === 'blue') {
document.body.classList.add(background)
}
})()

How to change style of multiple elements with a single script?

So basically I want to make a dark mode switcher for my website. I have a small script for start. It basically toggle the CSS style. But if I leave or refresh the page the style won't stay obviously...
<style>
.mystyle {
color:red !important;
background-color: black !important;
}
</style>
<script>
function init(){
var element = document.body;
element.classList.toggle("mystyle");
}
</script>
So my goal is to make this toggle button stay on its current state throughout the whole site even after refresh or change page...
A simple approach would be to save the state in localStorage, and when loading the page toggle the class according to its value.
Here is how you could implement it:
<style>
.dark-mode {
color: red;
background-color: black;
}
</style>
<body>
<button onclick="toggleMode()">Switch Mode</button>
</body>
<script>
const body = document.body;
if (localStorage.mode === 'dark') {
body.classList.add("dark-mode")
};
function toggleMode() {
body.classList.toggle("dark-mode");
localStorage.setItem(
'mode', localStorage.mode === 'light' || localStorage.mode === undefined ? 'dark' : 'light'
);
}
</script>
try removing and adding classes using add() and remove() functions, the following code may work:
<script>
var onOff=false; //to check of the class is active or not
function init(){
var element = document.body;
if(onOff === false){
element.classList.add("mystyle");
onOff = true;
}eles{
element.classList.remove("mystyle");
onOff = false;
}
}
</script>

Printing just an iFrame

I'm working on a case resolution system, and am currently using a jquery colorbox to display a list of open tasks to the user. Users want to be able to print this list, and I guess you can do it from within the page itself by adding a JavaScript link that triggers window.print from within the iframe. However, I've also got to account for users possibly selecting print from the browser's menu. In that case, if the colorbox is open, I just want to print its contents and not the overlying page.
Is it possible to hide everything except for the iframed content using a print media CSS file? If so, how can this be achieved? Failing that, I'll need to resort to JavaScript, so would achieving the effect in JavaScript be possible?
// suppose that this is how your iframe look like <iframe id='print-iframe' name='print-frame-name'></iframe>
// this is how you do it using jquery:
$("#print-iframe").get(0).contentWindow.print();
// and this is how you do it using native javascript:
document.getElementById("print-iframe").contentWindow.print();
In case the pure CSS solution will fail (didn't work for me but maybe I just missed something) you can have combined solution of CSS and JavaScript. First have this:
<style type="text/css" media="print">
.hideonprint { display:none; }
</style>
Then such JavaScript will cause all content to be hidden when printing, except your frame:
<script type="text/javascript">
window.onbeforeprint = function WindowPrint(evt) {
for (var i = 0; i < document.body.childNodes.length; i++) {
var curNode = document.body.childNodes[i];
if (typeof curNode.className != "undefined") {
var curClassName = curNode.className || "";
if (curClassName.indexOf("hideonprint") < 0) {
var newClassName = "";
if (curClassName.length > 0)
newClassName += curClassName + " ";
newClassName += "hideonprint";
curNode.setAttribute("original_class", curClassName);
curNode.className = newClassName;
}
}
}
document.getElementById("myframe").className = document.getElementById("myframe").getAttribute("original_class");
}
</script>
This also assume the iframe is direct child of the body otherwise it won't work either.
I have found a method that works to print just the IFrame's content even if the client uses the browser's print menu item, but I couldn't tell you why that is. The trick is to set the focus to the IFrame before printing. The print stylesheet is needed too, although the javascript seems to be what is happening when the user prints from the menu. You need both parts for it to work. It prints the entire document, even if it is larger than the IFrame! I have successfully tested it in IE8, Firefox 5 and 6 and Safari 3.2.
I use this script as a handler for an onclick event for a button or "print me" link:
<script type="text/javascript" language=JavaScript>
function CheckIsIE()
{
if (navigator.appName.toUpperCase() == 'MICROSOFT INTERNET EXPLORER')
{ return true; }
else
{ return false; }
}
function PrintThisPage()
{
if (CheckIsIE() == true)
{
document.content.focus();
document.content.print();
}
else
{
window.frames['content'].focus();
window.frames['content'].print();
}
}
</script>
The IFrame in question is named and id'd content. My button is in a div called print_iframe The browser sniffing is essential!
Then I use a print only stylesheet linked in like this:
<link href="/styles/print.css" rel="stylesheet" type="text/css" media="print" />
#charset "utf-8";
/* CSS Document */
body { background:none; }
#left { display:none; }
#main img { display:none; }
#banner
{
display:none;
margin-top:0px;
padding:0px;
}
#main
{
margin-top:0px;
padding:0px;
}
#print_iframe
{
display:none;
}
This could work if the iframe is a direct child of body
<style type="text/css" media="print">
body *{display:none}
iframe{display:block}
</style>

Toggle Visibility (Automatically causing one div element to hide when another is rendered visible)

Essentially what I am trying to do is create a website that has all of its content on the home page but only has some of the content visible at any one time. The way I read to do this is through toggling visibility.
The problem I am having is that: Assume the home page, when you first visit the website is blank (the way I want it to be). Lets say you click on the "about us" link. All of a sudden the about us section becomes visible (the way I want it to be). Now the problem that I have come across is when I know lets say click on the "products" link, I want the "products" content to become visible and the "about us" content to become invisible again. (Essentially creating the illusion of opening a new page within the same page).
Here is the code I have come up with so far. I can make certain div elements visible and invisible (onclick) but I can't figure out how to make sure only one div element is visible at any one time.
<script type="text/javascript">
function toggleVisibility() {
document.getElementById("about").style.display = "";
if(document.getElementById("about").style.visibility == "hidden" ) {
document.getElementById("about").style.visibility = "visible";
}
else {
document.getElementById("about").style.visibility = "hidden";
}
}
</script>
<script type="text/javascript">
function toggleVisibility1() {
document.getElementById("products").style.display = "";
if(document.getElementById("products").style.visibility == "hidden" ) {
document.getElementById("products").style.visibility = "visible";
}
else {
document.getElementById("products").style.visibility = "hidden";
}
}
</script>
The links to make the JavaScript work looks like this:
< href="#" onclick="toggleVisibility();">About
< href="##" onclick="toggleVisibility1();"> Products
here is another, simple function
<script type="text/javascript">
function toggle_visibility(id) {
var e = document.getElementById(id);
if(e.style.display == 'block')
e.style.display = 'none';
else
e.style.display = 'block';
}
</script>
if you click here, #foo will change visibility
<div id="foo">blablabla</div>
Without jQuery, you would want to do something like this:
<style type="text/css">
.content {
display: none;
}
#about {
display: block;
}
</style>
<script type="text/javascript">
function toggleVisibility(selectedTab) {
// Get a list of your content divs
var content = document.getElementsByClassName('content');
// Loop through, hiding non-selected divs, and showing selected div
for(var i=0; i<content.length; i++) {
if(content[i].id == selectedTab) {
content[i].style.display = 'block';
} else {
content[i].style.display = 'none';
}
}
}
</script>
About
Products
<div id="about" class="content">About stuff here</div>
<div id="products" class="content">Product stuff here</div>
Example here: http://jsfiddle.net/frDLX/
jQuery makes this much easier, but if you are beginning with JavaScript, sometimes you want to see the programmatic code, so you can tell what is going on.
This is exactly what jquery makes easier. Take this very simple example of what you're trying to achieve:
<style type="text/css">
.section {
display: none;
}
</style>
<script type="text/javascript">
function toggleVisibility(newSection) {
$(".section").not("#" + newSection).hide();
$("#" + newSection).show();
}
</script>
About
Products
<div id="about" class="section">about section</div>
<div id="products" class="section">products section</div>
Simple solution is like this:
<script type="text/javascript">
function toggleVisibility(divid) {
if (divid="about"){
document.getElementById("about").style.visibility = "visible";
document.getElementById("products").style.visibility = "hidden";
}
else if (divid="products")
{
document.getElementById("products").style.visibility = "visible";
document.getElementById("about").style.visibility = "hidden";
}
}
</script>
< href="#" onclick="toggleVisibility('about');">About
< href="##" onclick="toggleVisibility1('products');"> Products
use CSS display: property
element disappear
document.getElementById("products").style.display = "none";
element appear and is displayed as block (default for div)
document.getElementById("products").style.display = "block";
I posted sample code here: jQuery: menus appear/disappear on click - V2
PS
Here you can find nice examples about differences between display and visibility: http://wiw.org/~frb/css-docs/display/display.html

Categories