Can not set current light/dark mode into local storage - javascript

I am a javascript beginner and I am trying to integrate a simple light mode button. The default for my website is the dark mode. So the JS/CSS dark and light mode works fine. If the light mode is activated, the whole (external) CSS will be just replaced and it looks really great.
However here is my problem; The current mode of the CSS is not saved in the local storage. So when the user moves to the next HTML page, the default dark mode is back again.
I have already found many (really many) articles/forum posts etc. and tested a lot of sample codes (combined them etc.) but none of them worked for me.
Here is my JS code and a small part of my HTML/CSS. I've broken it up into individual snippets, because I assume that the snippet cannot visualize multiple HTML/CSS files, so you probably have to save and edit the pages locally.
Of course my question is; what do I need to change in the code so that the current Dark/LightMode setting is stored in the local storage and accessed on a page switch/reload etc.?
Thanks a lot for your effort in advance! :)
```
/* This is the light mode css */
body {
font-size: 21px;
font-family: Tahoma, Geneva, sans-serif;
max-width: 550px;
margin: 0 auto;
background-color: white;
}
h1 {
font-size: 30px;
color: white;
text-align: center;
text-shadow: 0px 0px 5px black;
margin: 40px 0 20px 0;
}
h2 {
font-size: 20px;
color: black;
text-align: center;
}
.btn-toggle {
background: white;
}
```
```
/* This is the dark mode css */
body {
font-size: 21px;
font-family: Tahoma, Geneva, sans-serif;
max-width: 550px;
margin: 0 auto;
background-color: black;
}
h1 {
font-size: 30px;
color: white;
text-align: center;
text-shadow: 0px 0px 5px black;
margin: 40px 0 20px 0;
}
h2 {
font-size: 20px;
color: white;
text-align: center;
}
.btn-toggle {
background: white;
}
```
```
<!-- this is the first HTML page -->
<!doctype html>
<html lang="en-gb">
<head>
<link rel="stylesheet" type="text/css" href="darkmode.css" id="theme-link">
</head>
<body>
<h1>Toggle Dark/lightmode example</h1>
<button class="btn-toggle">Toggle dark/light</button>
<button>Go to Site 2</button>
<h2>Unnecessary content</h2>
<script type="text/javascript" src="darkmode.js"></script>
```
```
<!-- this is the second page -->
<!doctype html>
<html lang="en-gb">
<head>
<link rel="stylesheet" type="text/css" href="darkmode.css" id="theme-link">
</head>
<body>
<h1>Toggle Dark/lightmode example</h1>
<button class="btn-toggle">Toggle dark/light</button>
<button>Go back to Site 1</button>
<h2>Unnecessary content</h2>
<script type="text/javascript" src="darkmode.js"></script>
<script>
// The JS file is usually eternally linked
// Select the button
const btn = document.querySelector(".btn-toggle");
// Select the stylesheet <link>
const theme = document.querySelector("#theme-link");
const currentTheme = localStorage.getItem("theme");
if (currentTheme == "dark") {
document.body.classList.toggle("dark-theme");
} else if (currentTheme == "light") {
document.body.classList.toggle("light-theme");
}
// Listen for a click on the button
btn.addEventListener("click", function() {
// If the current URL contains "dark-theme.css"
if (theme.getAttribute("href") == "kiblsstyle.css") {
// ... then switch it to "light-theme.css"
theme.href = "kiblsstylelight.css";
// Otherwise...
} else {
// ... switch it to "dark-theme.css"
theme.href = "kiblsstyle.css";
}
localStorage.setItem("theme", theme);
});
</script>
</body>
</html>
```

You shouldn´t try storing whole html element in local storage. Instead try storing theme name and then conditionally apply theme that you find in local storage. Here is your JS after clean up:
const btn = document.querySelector(".btn-toggle");
const styleLink = document.querySelector("#theme-link");
// Get stored theme with fallback value
const currentTheme = localStorage.getItem("theme") || "light";
if (currentTheme === "dark") styleLink.href = "kiblsstyle.css";
else if (currentTheme === "light") styleLink.href = "kiblsstylelight.css";
btn.addEventListener("click", () => {
if (styleLink.getAttribute("href") !== "kiblsstyle.css") {
styleLink.href = "kiblsstyle.css";
localStorage.setItem("theme", "dark");
} else {
styleLink.href = "kiblsstylelight.css";
localStorage.setItem("theme", "light");
}
});

localStorage was created to save simple, prinitive values and isn't intended to store DOM-elements. So you can just save boolean value in your case with just 2 themes. (When you'll create more of them, use few buttons or array, etc.) Or switch theme title but don't use DOM-object
localStorage article
const theme = document.querySelector("#theme-link");
const currentLightTheme = localStorage.getItem("isLight") || true;
btn.addEventListener("click", function() {
if (!currentLightTheme) {
theme.setAttribute('href', 'kiblsstylelight.css');
} else {
theme.setAttribute('href', 'kiblsstyle.css');
}
localStorage.setItem('isLight', !currentLightTheme)
});

Related

Localstorage - rewrite from JS to Jquery

I'm working on a portfolio project - which should use jquery - part of the task is to set and get text via localstorage - which I can do in Javascript but I breaks when attempting to refactor in jquery.
I found an elegantly simple javascript codepen, which has all the features I want. But when I refactor into jquery it loses funtionality - I can't save the text to local storage (I get null) and I can't copy the text to a different Div.
This is the HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Local Test</title>
</head>
<body>
<div class="content-output"></div>
<textarea class="content-input" placeholder="Your text here"></textarea>
<button class="save-button">Save</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="./script.js"></script>
</body>
</html>
This is simple CSS from the JS code pen:
* {
font-size: 16px;
font-family: sans-serif;
}
body {
padding: 1rem;
font-family: sans-serif;
}
.content-output {
float: left;
box-sizing: border-box;
background: #f9f9f9;
padding: 0.5rem;
width: calc(50% - 1rem);
height: 10rem;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
color: #202020;
}
.content-input {
float: left;
box-sizing: border-box;
margin-left: 2rem;
padding: 0.5rem;
width: calc(50% - 1rem);
height: 10rem;
border: 1px solid #505050;
resize: none;
}
.save-button {
/* -webkit-appearance: none; */
border: 0;
background: #0088ff;
padding: 0.5rem 1rem;
border-radius: 3px;
color: #fff;
margin-top: 1rem;
float: right;
cursor: pointer;
}
Here is the JS which works:
var input_textarea = document.querySelector(".content-input");
var output_div = document.querySelector(".content-output");
var save_button = document.querySelector(".save-button");
save_button.addEventListener("click", updateOutput);
output = localStorage.getItem("content");
input = localStorage.getItem("content");
console.log(output);
output_div.textContent = output;
function updateOutput() {
console.log("clicked button");
localStorage.setItem("content", input_textarea.value);
output_div.textContent = input_textarea.value;
}
And here is the jquery which doesn't work:
var input_textarea = $(".content-input");
var output_div = $(".content-output");
var save_button = $(".save-button");
save_button.on("click", updateOutput);
output_div.textContent = localStorage.getItem("content");
input_textarea.value = localStorage.getItem(("content"));
function updateOutput(event) {
event.preventDefault();
localStorage.setItem("content", input_textarea.value);
output_div.textContent = input_textarea.value;
}
I'm running out of ideas and searches - probably a typo but I cant find it . I've tried text() which was the advice 6 years ago. JSON.stringify and parse don't help because it's just a string.
I'm hoping someone has done some refactoring and spots the differences - I've even run this in the console but I can only add the text to localstorage manually: localstorage.setItem('content', 'help')
Thanks in advance
The problem is that you are trying to select a array, get the value of that array, and output to another array. I think jquery does that when you select a class, (because there could be more than one of them). Simple solution to this..
var input_textarea = $(".content-input")[0];
console.log(input_textarea)
var output_div = $(".content-output")[0];
var save_button = $(".save-button");
save_button.on("click", updateOutput);
output_div.textContent = localStorage.getItem("content");
input_textarea.value = localStorage.getItem(("content"));
function updateOutput(event) {
console.log('hello')
event.preventDefault();
localStorage.setItem("content", input_textarea.value);
output_div.textContent = input_textarea.value;
}
Found it: val() to set and text() to get.
var input_textarea = $(".content-input");
var output_div = $(".content-output");
var save_button = $(".save-button");
save_button.on("click", updateOutput);
// input_textarea.value = localStorage.getItem(("content"));
function updateOutput(event) {
event.preventDefault();
localStorage.setItem("content", input_textarea.val());
output_div.text(localStorage.getItem("content"));
}
this post helped: How to save the value of textarea to localstorage then display it in the same textarea

My page don't' work properly on dark mode how do I fix it?

I have This simple website that i need to make it change from light theme to dark theme, the light theme works fine, but the dark theme only changes its button properly because when i click in the button to change the "body" elements should change its class from "light-theme" to "dark-theme", instead it changes to "light-theme dark-theme"
here's HTML
`
<body class="light-theme">
<h1>Task List</h1>
<p id="msg">Current tasks:</p>
<ul>
<li class="list">Add visual styles</li>
<li class="list">add light and dark themes</li>
<li>Enable switching the theme</li>
</ul>
<div>
<button class="btn">Dark</button>
</div>
<script src="app.js"></script>
<noscript>You need to enable JavaScript to view the full site</noscript>
Heres CSS
:root {
--green: #00FF00;
--white: #FFFFFF;
--black: #000000;
}
.btn {
position: absolute;
top: 20px;
left: 250px;
height: 50px;
width: 50px;
border-radius: 50%;
border: none;
color: var(--btnFontColor);
background-color: var(--btnBg);
}
.btn:focus {
outline-style: none;
}
body {
background: var(--bg);
}
ul {
font-family: helvetica;
}
li {
list-style: circle;
}
.list {
list-style: square;
}
.light-theme {
--bg: var(--green);
--fontColor: var(--black);
--btnBg: var(--black);
--btnFontColor: var(--white);
}
.dark-theme{
--bg: var(--black);
--fontColor: var(--green);
--btnBg: var(--white);
--btnFontColor: var(--black);
}
and heres JavaScript
'use strict';
const switcher = document.querySelector('.btn');
switcher.addEventListener('click', function () {
document.body.classList.toggle('dark-theme')
var className = document.body.className;
if(className == "light-theme") {
this.textContent = "Dark";
} else {
this.textContent = "Light";
}
console.log('current class name: ' + className);
});
`
I tried to change some things in css but later found that the problem might be in the javascript, but my code is exactly as the code in my course is.
when i click in the button to change the "body" elements should change its class from "light-theme" to "dark-theme", instead it changes to "light-theme dark-theme"
That's indeed true - your JS code is only toggling the class "dark-theme" and does nothing with the "light-theme" class.
So a simple fix would be to toggle both classes:
switcher.addEventListener('click', function () {
document.body.classList.toggle('dark-theme')
document.body.classList.toggle('light-theme'); // add this line
var className = document.body.className;
if(className == "light-theme") {
this.textContent = "Dark";
} else {
this.textContent = "Light";
}
console.log('current class name: ' + className);
});
But you could simplify your code because you really don't need 2 classes here. If light theme is the default, just remove the light-theme class and all its CSS rules, and apply those to body instead. The .dark-theme rules will override these when the class is set, but not otherwise.

How to build a dark and light mode in html using different pages with codes?

I'm currently working on a website trying to build a settings page for the style of the website but I'm trying to use a different page with .css and .js so it doesn't just apply to one page it applies to all of the pages on the website.
Can someone work this out for me?
This is my current. CSS.css (for my CSS) page & JS.js (for my JavaScript) page.
const toggle = document.getElementById("toggle");
const refresh = document.getElementById("refresh");
const theme = window.localStorage.getItem("theme");
/* verifica se o tema armazenado no localStorage é escuro
se sim aplica o tema escuro ao body */
if (theme === "dark") document.body.classList.add("dark");
// event listener para quando o botão de alterar o tema for clicado
toggle.addEventListener("click", () => {
document.body.classList.toggle("dark");
if (theme === "dark") {
window.localStorage.setItem("theme", "light");
} else window.localStorage.setItem("theme", "dark");
});
refresh.addEventListener("click", () => {
window.location.reload();
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Definição das cores */
body {
/* cores de texto */
--text-white: #ffffff;
--text-dark: #142136;
/* cores de fundo */
--bg-grey-light: #f5f5f5;
--bg-white: #ffffff;
--bg-blue-dark: #142136;
--bg-indigo: #6366f1;
font-family: "Inter", sans-serif;
line-height: 1.7;
background-color: var(--bg-grey-light);
}
.dark {
--text-white: #e6e6e6;
--text-dark: #ffffff;
--bg-grey-light: #142136;
--bg-white: #22395d;
--bg-blue-dark: #142136;
--bg-indigo: #7577e1;
}
.container {
max-width: 600px;
margin: 40px auto;
display: flex;
padding: 20px;
flex-direction: column;
}
.text-wrapper {
width: 100%;
padding: 20px;
background-color: var(--bg-white);
margin-bottom: 40px;
border-radius: 10px;
}
.paragraph {
font-size: 16px;
color: var(--text-dark);
}
.heading {
font-size: 40px;
letter-spacing: 1px;
font-weight: 900;
margin-bottom: 40px;
color: var(--text-dark);
}
.buttons {
width: 100%;
display: flex;
justify-content: space-between;
margin-bottom: 40px;
}
.button {
width: 200px;
padding: 5px;
height: 40px;
border: none;
border-radius: 10px;
font-family: inherit;
cursor: pointer;
background-color: var(--bg-indigo);
color: var(--text-white);
font-size: 16px;
font-weight: 400;
text-transform: capitalize;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght#400;700&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="style.css" />
<title>Dark mode Tutorial</title>
</head>
<body>
<div class="container">
<h1 class="heading">
Dark/Light theme switcher with HTML, CSS & Javascript Only
</h1>
<div class="buttons">
<!-- botão para fazer a troca de estados dark/light -->
<button id="toggle" class="button">toggle</button>
<!-- botão para atualizar a página -->
<button id="refresh" class="button">refresh</button>
</div>
<div class="text-wrapper">
<p class="paragraph">
The United States shall be President of the States now existing shall
think proper to admit, shall not be questioned in any Department or
executed, and shall Commission all the Persons voted for, and
Conviction of, Treason, Bribery, or other Property belonging to the
which he was elected, be appointed to any civil Office under the
United States, at the time of the State Legislature.
</p>
</div>
<div class="text-wrapper">
<p class="paragraph">
Why, there's hardly enough of me left to make ONE respectable person!'
Soon her eye fell on a little glass box that was lying on the top of
her head though the doorway; `and even if I fell off the top of the
house!' (Which was very likely it can talk: at any rate, there's no
half afraid that it was only a mouse that had slipped in like herself.
`As wet as ever,' said Alice in a great hurry to change the subject of
must go by the carrier,' she thought; `and how funny it'll seem to dry
and she ran with all her knowledge of history, Alice had not a VERY
good opportunity for showing off her knowledge, as there was no `One,
two, three, and away,' but they began running when they liked, so that
it was too slippery; and when Alice had been all the way I want to go!
</p>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
You'll need to put in storage not just a single toggled state (a theme of light or dark), but such a state for every single page. Use the pathname as the key.
// Set the theme from storage on pageload:
if (!localStorage.darkThemesByPage) {
localStorage.darkThemesByPage = '{}';
}
const darkThemesByPage = JSON.parse(localStorage.darkThemesByPage);
const { pathname } = window.location;
if (darkThemesByPage[pathname]) {
document.body.classList.add("dark");
}
// Change the state in storage when the user wants to change theme:
const toggleDarkThemeForPage = () => {
// Retrieve storage again to preserve changes made on other pages
// after this page was loaded
const darkThemesByPage = JSON.parse(localStorage.darkThemesByPage);
darkThemesByPage[pathname] = !darkThemesByPage[pathname];
localStorage.darkThemesByPage = JSON.stringify(darkThemesByPage);
// Apply the new state of the theme after being toggled:
document.body.classList.toggle("dark", darkThemesByPage[pathname]);
};
Then just call toggleDarkThemeForPage when you need to toggle it, for example:
toggle.addEventListener("click", toggleDarkThemeForPage);
I'm using a boolean for the object values in storage above because it'll make toggling between light and dark easier - you just need to invert the truthyness of whatever the current state is. Then doing
document.body.classList.toggle("dark", darkThemesByPage[pathname]);
will apply the dark class if the value is true, and it'll remove the class otherwise.

how to permanently change/edit in css file by user input and save the chages in css files [duplicate]

Is it possible to alter a CSS stylesheet using JavaScript?
I am NOT talking about:
document.getElementById('id').style._____='.....';
I AM talking about altering:
#id {
param: value;
}
besides doing something dirty (which we haven’t tried yet btw), like creating a new object in the head, innerHTML a style tag in there, etc. Although this, even if it did work, would pose a few issues as the style block is already defined elsewhere, and I’m not sure when/if the browser would even parse a dynamically created style block?
Yes you can; every browser supports this, including IE9+).
The insertRule() method allows dynamic addition of rules to a stylesheet.
With deleteRule(), you can remove existing rules from a stylesheet.
Rules within a stylesheet can be accessed via the cssRules attributes of a stylesheet.
We can use a combination of .insertRule and .cssRules to be able to do this all the way back to IE9:
function changeStylesheetRule(stylesheet, selector, property, value) {
// Make the strings lowercase
selector = selector.toLowerCase();
property = property.toLowerCase();
value = value.toLowerCase();
// Change it if it exists
for(var i = 0; i < stylesheet.cssRules.length; i++) {
var rule = stylesheet.cssRules[i];
if(rule.selectorText === selector) {
rule.style[property] = value;
return;
}
}
// Add it if it does not
stylesheet.insertRule(selector + " { " + property + ": " + value + "; }", 0);
}
// Used like so:
changeStylesheetRule(s, "body", "color", "rebeccapurple");
Demo
2020
Some advantages of this method:
Does not require (but allows) stylesheet to be specified.
Allows multiple styles to be added / modified at once
Accepts !important attribute
Ignores extra whitespace when matching CSS selector
Changes last matching existing rule, or appends to end of last matching stylesheet. (Other answers add/change the first rule which may be then overruled.)
Usage:
adjustCSSRules('#myDiv', 'width: 300px !important');
Method:
function adjustCSSRules(selector, props, sheets){
// get stylesheet(s)
if (!sheets) sheets = [...document.styleSheets];
else if (sheets.sup){ // sheets is a string
let absoluteURL = new URL(sheets, document.baseURI).href;
sheets = [...document.styleSheets].filter(i => i.href == absoluteURL);
}
else sheets = [sheets]; // sheets is a stylesheet
// CSS (& HTML) reduce spaces in selector to one.
selector = selector.replace(/\s+/g, ' ');
const findRule = s => [...s.cssRules].reverse().find(i => i.selectorText == selector)
let rule = sheets.map(findRule).filter(i=>i).pop()
const propsArr = props.sup
? props.split(/\s*;\s*/).map(i => i.split(/\s*:\s*/)) // from string
: Object.entries(props); // from Object
if (rule) for (let [prop, val] of propsArr){
// rule.style[prop] = val; is against the spec, and does not support !important.
rule.style.setProperty(prop, ...val.split(/ *!(?=important)/));
}
else {
sheet = sheets.pop();
if (!props.sup) props = propsArr.reduce((str, [k, v]) => `${str}; ${k}: ${v}`, '');
sheet.insertRule(`${selector} { ${props} }`, sheet.cssRules.length);
}
}
Demo
The method takes three arguments:
selector [String] - CSS selector - eg: '#myDiv'
Whitespaces are auto-reduced (.myClass #myDiv will match .myClass #myDiv)
rules [CSS String, Object] - eg (either is acceptable):
{ border: "solid 3px green", color: "white" }
'border: solid 3px green; color: white'
sheet (Optional) [String, StyleSheet]
if empty, all stylesheets will be checked
'myStyles.css' A relative or absolute URL to sheet
document.styleSheets[1] - A reference to a sheet
Other examples:
adjustCSSRules('#myDiv', {width: '30px'}); // all stylesheets
adjustCSSRules('#myDiv', 'width: 30px', 'style.css'); // style.css only
adjustCSSRules('#myDiv .myClass', 'width: 30px', document.styleSheets[0]); // only first stylesheet
When I want to programmatically add a bunch of styles to an object, I find it easier to programmatically add a class to the object (such class has styles asscociated with it in your CSS). You can control the precedence order in your CSS so the new styles from the new class can override things you had previously. This is generally much easier than modifying a stylesheet directly and works perfectly cross-browser.
change a property in a style rule
function change_css_style (titulo,selector,propiedad,valor) {
let i=0;
while (i<document.styleSheets.length) {
if (document.styleSheets[i].title==titulo) {
let y=0;
while (y<document.styleSheets[i].cssRules.length) {
if (document.styleSheets[i].cssRules[y].selectorText==selector) {
document.styleSheets[i].cssRules[y].style[propiedad] = valor;
y = document.styleSheets[i].cssRules.length;
}
y++;
}
i=document.styleSheets.length;
}
i++;
}
}
DEMO
<style title="chat_inicio">
.contenido .mensajes {
width: 100px;
height: 300px;
}
</style>
change the style book with the title chat_inicio with the selector .contenido .mensajes the property of the style width to 475px
<script>
cambiar_css_style ('chat_inicio','.contenido .mensajes','width','475px');
</script>
.style.cssText property works, try the code below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
*{
margin: 0%;
padding: 0%;
}
html {
--theme-orange: orangered;
--theme-blue: rgb(67, 67, 197);
--theme-green: darkgreen;
--theme-black: black;
--theme-color: var(--theme-orange);
}
body {
font-family: 'Roboto', sans-serif;
background-color: rgb(251, 251, 251);
}
.nav-bar ul {
display: flex;
width: 100%;
background-color: var(--theme-color);
flex-wrap: wrap;
flex-direction: row;
align-items: center;
width: 100%;
}
.nav-bar ul a {
text-decoration: none;
margin: 15px 10px;
}
.nav-bar .theme {
background-color: white;
display: flex;
height: fit-content;
margin-left: auto;
margin-right: 20px;
border-radius: 10px;
}
.nav-bar .theme .box {
width: 20px;
height: 20px;
border: 1px solid black;
cursor: pointer;
}
.nav-bar .theme .orange {
background-color: var(--theme-orange);
}
.nav-bar .theme .blue {
background-color: var(--theme-blue);
}
.nav-bar .theme .green {
background-color: var(--theme-green);
}
.nav-bar .theme .black {
background-color: var(--theme-black);
}
.nav-bar ul li {
color: white;
font-weight: 500;
list-style: none;
padding: 10px 30px;
background-color: var(--theme-color);
transition: 0.2s;
}
.nav-bar ul li:hover {
box-shadow: inset 10px 10px 10px -12px;
scale: 0.95;
}
</style>
<body>
<div class="nav-bar">
<ul>
<li>Home</li>
<li>Page 1</li>
<li>Page 2</li>
<li>About Us</li>
<li>Contact Us</li>
<div class="theme">
<a><div class="box orange" id="orange"></div></a>
<a><div class="box blue" id="blue"></div></a>
<a><div class="box green" id="green"></div></a>
<a><div class="box black" id="black"></div></a>
</div>
</ul>
</div>
<script>
function colorChange(color) {
const htmlTag = document.getElementsByTagName("*")[0];
htmlTag.style.cssText = `--theme-orange: orangered;
--theme-blue: rgb(67, 67, 197);
--theme-green: darkgreen;
--theme-black: black;
--theme-color: var(--theme-${color});`;
}
function addEventListenerForBox() {
allBox = document.querySelectorAll('.box');
allBox.forEach(box => {
box.addEventListener('click', (event) => {
colorChange(event.target.id);
});
});
}
document.addEventListener('DOMContentLoaded', addEventListenerForBox);
</script>
</body>
</html>
Result:
One solution is:
Content CSS file:
#casesDndDropdown {
background: #FFFFFF;
border: 4px
}
You can override the #casesDndDropdown or any CSS class by defining it in the <style> tag inside body,
jQuery
$('<style>#id{background: #428bca;border: 0px}</style>').appendTo('body');
2023/2
A few years ago I read in w3schools: HTML style Tag that the <style> element supports the HTML Global Attributes and HTML Event Attributes.
The above means that, next to href, rel and target, any stylesheet can be disabled by toggling its disabled attribute. I had to dig deep to verify when and how this spec was implemented and found an old (November 2000) W3C document already mentioning support for the disabled attribute of a stylesheet.
tl;dr
putting disabled directly in the style definition like <style disabled> does not work.
toggling the disabled attribute false/true with Javascript disables/enables the entire referenced <style>...</style> block, wherever this block resides in your document.
Planning the position of style blocks in your document now becomes a matter of concern, as the regular browser logic is 'last in, first serve'.
All you need is a reference to a stylesheet element and a few Javascript oneliners:
function disabledToggle(e) { e.disabled = !e.disabled }
function disabledOff (e) { e.disabled = false }
function disabledOn (e) { e.disabled = true }
FYI
Check out the media attribute specification in the above W3C document.
The <link> element also supports the mentioned HTML Global Attributes and HTML Event Attributes.
Essentially, it has always been possible to kill a stylesheet with a single hipshot.
A simple proof of concept:
<html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<!-- Alternate font, activated in default <style>, but can be toggled on/off -->
<link id="lnk-poppins" href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
<!-- Default styling, considered 'always active' -->
<style>
* { box-sizing: border-box }
body { font-family: Poppins, sans-serif }
.square {
margin: 5rem auto;
width : 50vmin; aspect-ratio: 1;
background-color: CornflowerBlue;
}
</style>
<!-- Media controlled style, only active on small devices -->
<style media="all and (max-width: 640px)">
body {
margin: 0; padding: 1rem;
width: 100%; min-height: 100vh;
background-color: hsl(90,100%,50%,.3);
}
</style>
<!-- Alternative styles: last in, first serve, so order matters -->
<style id="stl-red" >.square { background-color: Red }</style>
<style id="stl-green">.square { background-color: Green }</style>
<style id="stl-blue" >.square { background-color: Blue }</style>
<!-- Default style, but can be toggled: overrides all above when enabled -->
<style id="stl-default" >.square { background-color: Black }</style>
</head>
<body>
<fieldset>
<legend> Style Toggles </legend>
<p>Colors:</p>
<label for="default">
<input id="default" class="radio" type="radio" name="group" checked
oninput="disabledOff(defa);">
Default
</label>
<label for="red">
<input id="red" class="radio" type="radio" name="group"
oninput="disabledOff(red);disabledOn(defa);disabledOn(blue);disabledOn(green);">
Red
</label>
<label for="green">
<input id="green" class="radio" type="radio" name="group"
oninput="disabledOff(green);disabledOn(defa);disabledOn(blue);">
Green
</label>
<label for="blue">
<input id="blue" class="radio" type="radio" name="group"
oninput="disabledOff(blue);disabledOn(defa);">
Blue
</label>
<p>Font:</p>
<label for="poppins">
<input id="poppins" type="checkbox" oninput="disabledToggle(popp);" checked>
Poppins
</label>
<br><br>
<span>Old W3C Reference: <a target="_blank" href="https://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-StyleSheet-disabled">Attributes: <b>disabled</b> of type boolean</a></span>
</fieldset>
<div class="square"></div>
<script>
const red = document.getElementById('stl-red');
const green = document.getElementById('stl-green');
const blue = document.getElementById('stl-blue');
const defa = document.getElementById('stl-default');
const popp = document.getElementById('lnk-poppins');
function disabledToggle(e) { e.disabled = !e.disabled }
function disabledOff (e) { e.disabled = false }
function disabledOn (e) { e.disabled = true }
</script>
</body>
</html>

Something breaks when Chrome developer tools are open

I made a quote generator and it works fine with the Chrome developer tools open, but then won't generate a new quote when the developer tools are closed. This happens with my project in CodePen. On my computer, it generates a quote three times (works fine the first three clicks of the generate quote button) then stops working. It's not working at all in Safari. Why would this be?
I'm sure my JavaScript could use some refactoring too, any help there would also be great. Thanks!
Link to CodePen Demo
HTML
<html>
<head>
<title>Random Quote Generator</title>
<link rel="stylesheet" type="text/css" href="css/quote.css">
<link href='https://fonts.googleapis.com/css?family=Lato:300italic,300' rel='stylesheet' type='text/css'>
</head>
<body>
<div class="quote-container">
<div class="quote" id="msg"></div>
</div>
<div class="button-container">
Get Quote
</div>
<div id="twtbtn"></div>
<script src="https://code.jquery.com/jquery-3.0.0.min.js" integrity="sha256-JmvOoLtYsmqlsWxa7mDSLMwa6dZ9rrIdtrrVYRnDRH0=" crossorigin="anonymous"></script>
<script type="text/javascript" src="js/quote.js"></script>
</body>
</html>
CSS
body {
background: linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)), url('https://images.unsplash.com/photo-1437652010333-fbf2cd02a4f8?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&s=2330269f135faf1c33bf613b85d5f1df');
background-size: cover;
background-repeat: no-repeat;
background-position: center center;
}
* {
font-family: 'Lato', sans-serif;
}
.quote-container {
display: flex;
flex-direction: column;
justify-content: center;
}
.quote {
width: 80%;
text-align: center;
margin: 0 auto;
font-size: 48px;
font-style: italic;
color: white;
}
.button-container {
margin: 30px auto 50px auto;
text-align: center;
}
#button {
border: 1px solid white;
padding: 12px 30px;
background: transparent;
font-size: 18px;
border-radius: 2px;
}
#button:hover {
background-color: white;
}
a {
text-decoration: none;
color: white;
}
a:hover {
color: black;
};
JavaScript
$(document).ready(function(){
//get quote from random quote API
$.getJSON("http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&callback=", function(a) {
//append quote and author to document
$(".quote").append(a[0].content + "<p>— " + a[0].title + "</p>")
//initiate twitter button function
window.twttr = (function (d,s,id) {
var t, js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return; js=d.createElement(s); js.id=id;
js.src="https://platform.twitter.com/widgets.js"; fjs.parentNode.insertBefore(js, fjs);
return window.twttr || (t = { _e: [], ready: function(f){ t._e.push(f) } });
}(document, "script", "twitter-wjs"));
//insert tweet button
insertTweetBtn();
});
});
$("a").click(function(){
//get quote from random quote API
$.getJSON("http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&callback=", function(a) {
//replace HTML with newly generated quote
$(".quote").html(a[0].content + "<p>— " + a[0].title + "</p>")
//remove contents of tweet button div
$("#twtbtn").empty();
//insert new tweet button to grab newly generated quote
insertTweetBtn();
});
});
function insertTweetBtn() {
var msg = document.getElementById('msg').textContent;
twttr.ready(function (twttr) {
twttr.widgets.createShareButton(
'',
document.getElementById('twtbtn'),
function (el) {
console.log("Button created.")
},
{
text: msg ,
}
);
twttr.events.bind('tweet', function (event) {
console.log(event, event.target);
});
});
}
Ok...so i was going crazy trying to figure it out then I went to the documentation for getJSON for jquery. I am not 100% about JSONP but thats the thing, when you add the &callback into the url..it uses JSONP. So I removed it and it works great in safari. Here is the codepen
FIXED
and here is the quote from jquery:
"If the URL includes the string "callback=?" (or similar, as defined by the server-side API), the request is treated as JSONP instead. See the discussion of the jsonp data type in $.ajax() for more details."
$.getJSON("http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1", function(a) {stuff}
This unfortunately doesn't explain why safari is the only one it didn't work in...but hey, it fixes it :)

Categories