Keep dark or light mode over different pages with javascript - javascript

Basically, I got a dark mode on the front page, with the script being (from W3schools) :
<script>
function darklightmode() {
var element = document.body;
element.classList.toggle("dmode");
} </script>
And the button :
<button onclick="darklightmode()" style="background:none; border: none;">
<img src="images/ld-icon.png" class="icon">
</button>
and some CSS just for example :
.dmode li a{
transition: 1s all;
color: #2E3440;
background: none;}
So how can I, with some Javascript, make the mode the user is using stay between pages and not come back to default when accessing another page ?
Beginner here, any help appreciated.

You'd need to store the current theme somewhere. Try using localstorage.
Example from How do i set dark mode theme across multiple pages? (this question is a duplicate):
checkbox.addEventListener( 'change', function() {
localStorage.setItem('dark',this.checked);
if(this.checked) {
body.classList.add('dark')
} else {
body.classList.remove('dark')
}
});
and this on each page:
if(localStorage.getItem('dark')) {
body.classList.add('dark');
}

Related

How to remember the buttons click state and their functions with local storage?

I have many buttons that change/add/remove elements. Some of the elements are dynamic e.g. clicking button one will create button two etc.
I'd like to save the state of the buttons/page in local storage. If I clicked button one, and then two, the background is now red. When the visitor returns (after browser close) it will be as if they have already clicked one>two and will see the red background as before.
I've been reading Mozilla setItem and every post on Stackoverflow about local storage but I can't find any examples of this exact scenario.
https://jsfiddle.net/oh9q2Lzw/1/
$('.one').on('click', function() {
$('.blue').removeClass('blue').addClass('green');
});
$('.two').on('click', function() {
$('.green').removeClass('green').addClass('red');
});
button {
padding: 10px 40px;
}
.blue {
width: 200px;
padding: 20px;
background: blue
}
.green {
width: 200px;
padding: 20px;
background: green
}
.red {
width: 200px;
padding: 20px;
background: red
}
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
<br>
<div class="box">
<button class="one">one</button>
<button class="one">one</button>
<button class="two">two</button>
</div>
<br>
<div class="blue"></div>
<br>
<div class="blue"></div>
In your example, the only memory the page needs is the class name of the divs applied when the style was last changed.
Therefore, the simple solution is to store the class name in local storage each time it changes by modifying your button events as follows:
$('.one').on('click', function() {
$('.blue').removeClass('blue').addClass('green');
localStorage.setItem("div-class", "green");
});
$('.two').on('click', function() {
$('.green').removeClass('green').addClass('red');
localStorage.setItem("div-class", "red");
});
When the page loads, the hard-coded class is always "blue" and so this can be changed if a value is stored in local storage.
This is done by adding a function to the window.onload event:
window.onload = function() {
if (localStorage.getItem("div-class")) {
$('.blue').removeClass('blue').addClass(localStorage.getItem("div-class"));
}
};
The SO snippet tool doesn't allow local storage access but I've modified your JS fiddle with a working example: https://jsfiddle.net/g5wqjo2h/
I've also made a modified version with an extra button to allow you to clear localStorage during development. If the clear memory button is clicked, when the js Fiddle is next run or loaded, the divs return to the default blue class. Otherwise, the previous colour is loaded from localStorage. : https://jsfiddle.net/g5wqjo2h/1/

Remembering color-choice through Jquery (localStorage)

I have created a very simple and basic Jquery script that changes the class for textboxes on my site in order for them to have a different colored background when a button is clicked. I then attempted (with the help of a Jquery-for-dummies-book) to set it up so that the color choice is remembered locally.
I must however be a greater "dummy" than expected because I have not been able to make this work.When I upload the script to the server and test it on the site, I can change the color, but if I close then window and then go to my website again, the color is back to default. It is NOT remembered/stored.
Is it possible the problem stems from the fact that my textboxes use the class "row" to set the background color, and you can not change a class to a different class, but must use a proper element or ID? Or should the order of the script-parts perhaps be different?
Any and all insight is appreciated on my learning-journey.
External script
$(document).ready(function(){
if (localStorage.getItem("farvevalg")=="farve") { $(".row").addClass("farve");
}
if ($(".row").hasClass("farve")) {
localStorage.setItem("farvevalg", "farve");
} else {localStorage.removeItem("farvevalg")}
$('#farvevalg').click(function(){
$(".row").toggleClass('farve');
}); }
My HTML
/*The default color of all textboxes on a page*/
.row {background-color: #e7e7e7;}
/*The color that it changes into when button is clicked*/
.farve {background-color: pink;}
/*The button that must be clicked to change color*/
#farvevalg {
margin-top: 6%;
padding: 5px;
}
Your attempt is correct but add/remove localStorage you are doing at the wrong place. You should do it inside that button click.
WORKING FIDDLE
Snippet won't work because of the CORS issue. It's for code view only.
$(document).ready(function () {
if (localStorage.getItem("farvevalg") == "farve") {
$(".row").addClass("farve");
}
$('#farvevalg').click(function () {
$(".row").toggleClass('farve');
if ($(".row").hasClass("farve")) {
localStorage.setItem("farvevalg", "farve");
} else {
localStorage.removeItem("farvevalg")
}
});
});
/*The default color of all textboxes on a page*/
.row {background-color: #e7e7e7;}
/*The color that it changes into when button is clicked*/
.farve {background-color: pink;}
/*The button that must be clicked to change color*/
#farvevalg {
margin-top: 6%;
padding: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<div class="row">
Test
</div>
<button id="farvevalg">
Change
</button>
some changes in login, not tested but should work
$(document).ready(function(){
if (localStorage.getItem("farvevalg")=="farve") {
$(".row").addClass("farve");
}
$('#farvevalg').click(function(){
//only here we add/remove setting
var wasFarveColor = $(".row").hasClass("farve")
$(".row").toggleClass('farve');
if(wasFarveColor)
localStorage.removeItem("farvevalg")
else
localStorage.setItem("farvevalg", "farve")
});
})
what you are doing is, at the start of your application, check it there is a saved item 'farvevalg' with value 'farve'. If that is the case, then you add the class 'farve' to all elements with class 'row'.
After this you check if there is a row element with class 'farve' and, if that is the case' you set the item in storage, otherwise you delete it. As you can see it doesn't make sense for this bit of code to be here as it won't have any effect. You should instead move this if/else block inside of the click callback ( after $(".row").toggleClass('farve'); )

CSS manipulation using buttons

I am trying to make a small settings page where users can change how the site looks, I want them to be able to click a button and the sites CSS update along with it (along with the background colo(u)r) and I would like the changes saved across all pages.
How would I do this?
From your question, I have come up with a solution that suits your use case better in a neater implementation.
Take the following code for example;
<div id="container">
<div>
<h1>Page Header</h1>
<h3>Page Sub Header</h3>
<p>Page Content</p>
</div>
<div class="buttons">
<button id="default-theme" onclick="setTheme(event)">default</button>
<button id="theme-one" onclick="setTheme(event)">theme one</button>
<button id="theme-two" onclick="setTheme(event)">theme two</button>
</div>
</div>
In the code above, you have some unstyled elements and some buttons to set the preferred theme color.
You can set the theme colors like below in your CSS file. The code below is an SCSS implementation. Check out the live solution on codePen https://codepen.io/sirwhite/pen/mdbNjLG
<style>
// Default theme color
.default-theme {
background: $default-bg;
}
.default-theme h1 {
color: $default-color;
}
.default-theme h3 {
color: $default-color;
}
.default-theme p {
color: $default-color;
}
// Theme One Colors
.theme-one {
background: $theme-one-bg;
}
.theme-one h1 {
color: $theme-one-color;
}
.theme-one h3 {
color: $theme-one-color;
}
.theme-one p {
color: $theme-one-color;
}
// Theme Two Colors
.theme-two {
background: $theme-two-bg;
}
.theme-two h1 {
color: $theme-two-color;
}
.theme-two h3 {
color: $theme-two-color;
}
.theme-two p {
color: $theme-two-color;
}
</style>
Now, use javascript to set the theme color based on the user's selection
var theme = '';
var container = document.getElementById('container');
window.addEventListener('load', function() {
if(localStorage.theme && localStorage.theme !== '') {
theme = localStorage.theme;
container.classList.add(theme);
}
else {
theme = 'default-theme';
}
});
function setTheme(event) {
theme = event.target.id ;
localStorage.theme = theme;
container.classList = [];
container.classList.add(theme);
}
You can use LocalStorage to persist the selected theme value across all pages. When the page loads, you can check if localStorage value is set else set the theme to the default theme.
Check out the live solution on codePen https://codepen.io/sirwhite/pen/mdbNjLG
You could do this with javascript or jquery by calling a function when your button is clicked.
Our HTML, notice how we call myFunction when we click on the button.
<h1 class="item blue">Hello World</h1>
<button onClick="myFunction()">Click Me</button>
Some basic CSS:
.blue {
color: blue;
}
.red {
color: red;
}
Our Javascript will add a class depending on what class is already present. We can change our target variable to add/remove classes from a different element.
function myFunction() {
var target = document.querySelector('.item');
if (target.classList.contains('red')) {
target.classList.remove('red')
target.classList.add('blue')
} else if (target.classList.contains('blue')) {
target.classList.add('red')
target.classList.remove('blue')
}
}
This is a very cookie-cutter way of doing this, but it works and you can take the same principles here and apply it to your code.
To use this site-wide, just use a seperate javascript file and import the same javascript and call the same function on each page.
Hope this helps :)
As per my understanding of the question you want to change the background colour on the button click
<!DOCTYPE html>
<html>
<head>
<style>
.yellows {
background: yellow;
}
</style>
<script src="https://code.jquery.com/jquery-3.4.1.js"></script>
</head>
<body>
<button id="btn">click me </button>
<script>
$('#btn').click(function() {
$('body').toggleClass( "yellows" );
});
</script>
</body>
</html>

How to change one HTML file to another without changing link?

I have an html file(a webpage). I want when I press a button on it, the page should be replaced by another html file (with its own css, javascript functions etc) without being redirected to some other link.
For example, if link in first case is abc.com/def it should be same after too.
Using this code, I am able to change webpage look, but not getting how to change look (and also manage to load css and js functions) from another file.
<script type="text/javascript">
document.body.addEventListener('click',function(){
document.write("THIS IS NEW TEXT")
},
false);
</script>
You need to look into frameworks like AngularJS, Specially Routing of Angular. They provide such features built-in for web applications. However, you can do it the hard way, using javascript, like you are doing it right now. Add CSS and change whole body HTML using javascript if you don't want to learn any new framework or libraries.
You want to use PJAX,
Here's a link for an example.
As discuss by others, you should use a Framework to do this..
But this is a complete solution you can inspire of:
let layouts = {}
let current = null
// Display the new page by deleting current, and replacing by the good one
let displayLayout = (layout_id) => {
let parentNode = current.parentNode
parentNode.removeChild(current)
current = layouts[layout_id]
parentNode.appendChild(current)
loadEvents(current)
}
// Load event for HTML DOM you just created
let loadEvents = (layout_el) => {
Array.from(layout_el.getElementsByClassName('go-to-layout')).forEach(el => {
el.addEventListener('click', e => {
e.preventDefault()
displayLayout(e.currentTarget.dataset.layout)
})
})
}
// On init I get all the existing layout, but you can build you own dictionary an other way.
Array.from(document.getElementsByClassName('layout')).forEach(l => {
layouts[l.id] = l
if (l.classList.contains('active')) {
loadEvents(l)
current = l
}
else {
l.parentNode.removeChild(l);
}
})
/* Global CSS */
body, html, .layout {
height: 100%;
margin: 0;
}
* {
color: #FFF
}
.layout {
display: flex;
}
.nav, .page {
}
.nav {
width: 150px;
background: #555;
}
/* Special CSS for one layout */
#layout1 {
background: red;
}
#layout2 {
background: blue;
}
<div id="layout1" class="layout active">
<div class="nav">
Page 2
</div>
<div class="page">
This is page 1
</div>
</div>
<div id="layout2" class="layout">
<div class="nav">
Page 1
</div>
<div class="page">
This is page 2
</div>
<style>.page { font-size: 2em }</style>
</div>

More efficient way to change styles using Javascript?

I have an about section, where I've split it up into multiple sections loaded by JavaScript for easier reading. I'd like the side navigation for this to have a different background color if it is both hovered over and if it is the one selected, and ALSO to have a border right with a unique color for each option. I have it working with no problems, but I'm just wondering if there is a more efficient way to do this than the way I currently am.
In a nutshell, the HTML:
<nav>
<p id="bout" onclick="bout()">About Us</p>
<p id="mish" onclick="mish()">Our Mission</p>
<p id="team" onclick="team()">The Team</p>
<p id="how" onclick="how()">How It Works</p>
<p id="poli" onclick="poli()">Policies</p>
</nav>
<div class="actual">
<div id="about">
<h2>About Us</h2>
<p>We are a conglomerate of hoodlums.</p>
</div>
</div><!-- end actual -->
And the JS:
function bout() {
document.getElementById("about").innerHTML= '<h2>About Us</h2><p>We are a conglomerate of hoodlums.</p>';
document.getElementById("bout").style.borderRight='3px solid red';
document.getElementById("mish").style.borderRight='none';
document.getElementById("team").style.borderRight='none';
document.getElementById("how").style.borderRight='none';
document.getElementById("poli").style.borderRight='none';
document.getElementById("bout").style.backgroundColor='ghostwhite';
document.getElementById("mish").style.backgroundColor='bisque';
document.getElementById("team").style.backgroundColor='bisque';
document.getElementById("how").style.backgroundColor='bisque';
document.getElementById("poli").style.backgroundColor='bisque';
}
function mish() {
document.getElementById("about").innerHTML = '<h2>Mission</h2><p>Our mission is to rid the world of dust bunnies.</p>';
document.getElementById("bout").style.borderRight='none';
document.getElementById("mish").style.borderRight='3px solid orange';
document.getElementById("team").style.borderRight='none';
document.getElementById("how").style.borderRight='none';
document.getElementById("poli").style.borderRight='none';
document.getElementById("bout").style.backgroundColor='bisque';
document.getElementById("mish").style.backgroundColor='ghostwhite';
document.getElementById("team").style.backgroundColor='bisque';
document.getElementById("how").style.backgroundColor='bisque';
document.getElementById("poli").style.backgroundColor='bisque';
}
As you can see, it's quite cumbersome to have to explicitly turn off an on each style when clicked. The main key though is to have each border-right be a different color.
Here is a jsfiddle with the whole thing, but for some reason it's not actually acknowledging the JS: http://jsfiddle.net/4CrhD/
Additional random question: Is it possible to link to this page with a different piece of content loaded than about, for example, can I link to this page with "mish()" loaded instead of whats in the HTML?
The best way would be to use CSS. Add remove a class on a parent element and have the CSS apply the right rules.
body.mish #bout{
border-right : 3px solid red,
}
body.bout #bout{
border-right : 3px solid blue,
}
Yes. You need to divide between html and styling. Use CSS!
Then you can change styles e.g. with jQuery.css():
$('#mish').css({
'border-right': '3px solid orange',
'background-color':'ghostwhite'
});
Of course you can define styles in a class. A class describes the styling definition for all elements using a class.
nav > p {
border-right: none;
background-color: bisque;
}
.active {
border-right: 3px solid red;
background-color: ghostwhite;
}
If a button is clicked you can dynamically add and remove a classes with:
$('nav > p').click(function() {
$('nav > p').removeClass('active');
$(this).addClass('active')
});
Because code duplication is bad (and I don't like to set the full innerHTML), you can create a dynamic page like:
pages = {
'bout': {
'id': 'about',
'headline': 'About Us',
'body': 'We are a conglomerate of hoodlums.'
}
}
Extend the above code to
$('nav > p').click(function() {
$('nav > p').removeClass('active');
$(this).addClass('active')
if (pages[$(this).attr('id')]) {
var page = pages[$(this).attr('id')];
$('.actual').first().empty();
var container = $('<div>', { 'id': page.id });
container.append($('<h2>', { 'html': page.headline }));
container.append($('<p>', { 'html': page.body }));
$('.actual').first().append(container);
}
});
Have look at this jsfiddle for a working example
Addressing your "random" question
Additional random question: Is it possible to link to this page with a different piece of content loaded than about, for example, can I link to this page with "mish()" loaded instead of whats in the HTML?
If you want to have links pointing to this page you can parse the window.location.hash object and link with links like page.html#mish.
To set default a "page" we extend our pages object to provide such a information: http://jsfiddle.net/Eu36g/6/
Define your classes in the CSS : bout, mish, about, poli ... For each one put the CSS you want. After that, in the javascript, you just have to change the class of the element (add class or change class, or whatever) and the new CSS will apply
example
document.getElementById("bout").className = "otherclass"

Categories