I have a toggle with and a script to switch between stylesheets but i don't know how to store the toggle state
I know there are multiple questions like this but none using a toggle and local storage with 2 stylesheets (rather css variables or something else, my css is a terrible mess and can't make those work). I'm a UI designer with some knowledge of HTML/CSS and i barely find time to learn JS.
<link id="theme" rel="stylesheet" type="text/css" href="default.css" />
<input type="checkbox" id="tog"/>
<label for="tog" class="toggle" onclick="toggle()"></label>
<script type='text/javascript'>
function toggle() {
var el = document.getElementById("theme");
if (el.href.match("default.css")) {
el.href = "dark.css";
}
else {
el.href = "default.css";
}
}
</script>
This works great but i need the toggle to be saved so it won't change back after a refresh. And from what i've read it's done with local storage but it's beyond me.
I see examples here with multiple links/buttons for each style but i can't adapt them to a toggle. I've tried. Could you help?
Like this:
function toggle(theme) {
var styleSheet = document.getElementById("theme");
if (theme != styleSheet.href) styleSheet.href = theme;
document.getElementById("tog").checked = styleSheet.href === "dark.css";
}
window.addEventListener("load",function() {
var theme = localStorage.getItem("theme") || document.getElementById("theme").href;
toggle(theme);
document.getElementById("tog").addEventListener("change",function() {
var theme = this.checked ? "dark.css" : "default.css"
toggle(theme);
localStorage.setItem("theme",theme);
})
})
<link id="theme" rel="stylesheet" type="text/css" href="default.css" />
<label>Toggle to dark theme <input type="checkbox" id="tog"/></label>
<script>
function toggle() {
var el = document.getElementById("theme");
var theme = (el.href === 'default.css') ? 'dark.css' : 'default.css';
el.href = theme;
localStorage.setItem('theme', theme);
}
function defaultTheme() {
var el = document.getElementById('theme');
var theme = localStorage.getItem('theme');
if (theme) {
el.href = theme
}
}
defaultTheme();
</script>
Related
There's lots of examples on Stackoverflow on how to detect IE11, but I'm not sure how to use it in a JavaScript conditional statement.
I'm using Tailwind CSS, but it doesn't support IE11 and below. I'd like a way to at least provide some kind of layout via an alternative CSS files.
How would I do something like this with JavaScript?
if (IE11) {
<link rel="stylesheet" href="/css/ie11.css">
} else if (IE10) {
<link rel="stylesheet" href="/css/ie10.css">
} else if (IE9) {
<link rel="stylesheet" href="/css/ie9.css">
} else if (IE8) { {
<link rel="stylesheet" href="/css/ie8.css">
} else {
<link rel="stylesheet" href="/css/tailwind.css">
}
}
I appreciate global IE11 usage is very low, but I'd like to be able to make use of Tailwind CSS and offer the option of supporting older browsers if needed.
You can use window.document.documentMode to determine if the current browser is IE. Then dynamically import resources into the page.
Simple code:
<script>
var ieVersion = window.document.documentMode;
if (ieVersion != 'undefined' & ieVersion > 7 && ieVersion < 12) {
console.log('Load in IE ' + ieVersion);
importJsResource(ieVersion);
} else {
console.log('Not in IE 8-11..');
ieVersion = "tailwind";
importJsResource(ieVersion);
}
function importJsResource(version) {
var fileref = document.createElement("link");
fileref.rel = "stylesheet";
fileref.type = "text/css";
if (ieVersion == 'tailwind') {
fileref.href = "/Content/tailwind.css";
} else {
fileref.href = "/Content/ie" + version + ".css";
}
document.getElementsByTagName("head")[0].appendChild(fileref);
}
</script>
I'm making a page with lots of iframes on it, the websites in the iframes have ads in them and to make the page more viewable to people with adblock, I need to display different stylesheets.
Basically what I want to do is.. if adblock (display this stylesheet) else (display this stylesheet).
I have the code working to detect if adblock is present, but when I try to do the if else statement..the whole page is blank. Here's the code:
<script>
(function(){
if($("#fakead").css('display')=="none")
{
document.write("<link href='css/adblock.css' rel='stylesheet' type='text/css'>")
}
else
{
document.write("<link href='css/noadblock.css' rel='stylesheet' type='text/css'>")
}
});
</script>
I'm extremely new to Javascript so my apologies if the code is terrible.
Thanks for any help
You should not use document.write method. As I see you use jQuery, so in jQuery you can do like this:
$( function() {
if($("#fakead").css('display')=="none") {
$("<link href='css/adblock.css' rel='stylesheet' type='text/css'/>").appendTo( 'head' );
} else {
$("<link href='css/noadblock.css' rel='stylesheet' type='text/css'/>").appendTo( 'head' )
}
});
Please note: link element should be placed in <head> section. Read more in w3c.
Pure JS option:
var el = document.createElement("link");
el.type = "text/css";
el.rel = "stylesheet";
el.href = "style.css";
document.getElementsByTagName("head")[0].appendChild(el);
Does anyone know how I can change the entire document's CSS file on click? I've searched around but only found a few results on setting a class/ID's CSS, not the entire document. My website has two themes, light/dark, and I want to load up "light.css" or "dark.css" from two links.
Thanks.
You need to change the src of the the link tag, which controls the styles. For example, you probably have this in your head tag:
<link rel="stylesheet" href="light.css">
You need to change the href attribute of the link tag to "dark.css" when you click something. You can do that like this:
document.getElementById('id-of-element').addEventListener('click',function(){
document.getElementsByTagName('link')[0].setAttribute('href',isDark?'light.css':'dark.css');
isDark=isDark?false:true;
}
IMPORTANT: you need to set isDark to false or true before this code, depending on whether the page is supposed to be dark or light in the beginning. You also need to change id-of-element to the id of the element that should be clicked to toggle the state of the page.
I think this is better than the other answers because it is simpler and uses no jquery.
EDIT: I accidentally had the src attribute instead of the href one before. I now updated it to be correct.
Yeah, you can do using theming. But the changing of CSS is limited to the <body> tag.
$("a.theme").click(function(){
$("body").addClass("dark");
});
I have used jQuery library to make the coding easier. And it is not a good idea to switch CSS rather, you can change the classes.
Demo
You can check out the working demo in jsBin.
Check out this answer for more details: Selecting a web page look and feel without reloading, with one CSS.
Try something like this:
Light
Dark
<script type="text/javascript" charset="utf-8">
$('a#light, a#dark').click(function(){
$('style').remove();
$.ajax({
url:'http://www.example.com/' + $this.attr('id') + '.css',
success:function(data){
$('<style></style>').appendTo('head').html(data);
}
})
})
</script>
Of course, you need to load jQuery first.
There's 2 ways that come immediately to mind.
1) Add a style tag to the page's head, ensuring that the style tag has a unique id. You can then set the innerHTML of that element. (somewhat messy)
2) Add a link tag to the page's head, also ensuring that it has a unique id. You set the type='text/css' and the rel='stylesheet' attributes. You the set the src of this link element to the appropriate css file.
Here's an example of each type. Just supply css files for theme3() and theme4() functions.
Example:
<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}
function newEl(tag){return document.createElement(tag);}
function newTxt(txt){return document.createTextNode(txt);}
function toggleClass(element, newStr)
{
index=element.className.indexOf(newStr);
if ( index == -1)
element.className += ' '+newStr;
else
{
if (index != 0)
newStr = ' '+newStr;
element.className = element.className.replace(newStr, '');
}
}
function forEachNode(nodeList, func)
{
var i, n = nodeList.length;
for (i=0; i<n; i++)
{
func(nodeList[i], i, nodeList);
}
}
window.addEventListener('load', mInit, false);
function mInit()
{
var style = newEl('style');
style.setAttribute('id', 'dynCss');
document.head.appendChild(style);
var style2 = newEl('link');
style2.setAttribute('type', 'text/css');
style2.setAttribute('rel', 'stylesheet');
style2.setAttribute('id', 'dynCss2');
document.head.appendChild(style2);
}
function theme1()
{
var style = byId('dynCss');
style.innerHTML = "h1{color: red;}";
var style2 = byId('dynCss2');
style2.setAttribute('href', '');
}
function theme2()
{
var style = byId('dynCss');
style.innerHTML = "h1{color: blue;}";
var style2 = byId('dynCss2');
style2.setAttribute('href', '');
}
function theme3()
{
var style = byId('dynCss');
style.innerHTML = "";
var style2 = byId('dynCss2');
style2.setAttribute('href', 'style3.css');
}
function theme4()
{
var style = byId('dynCss');
style.innerHTML = "";
var style2 = byId('dynCss2');
style2.setAttribute('href', 'style4.css');
}
</script>
<style>
</style>
</head>
<body>
<h1>This is the heading</h1>
<input type='button' onclick='theme1();' value='Theme 1'/>
<input type='button' onclick='theme2();' value='Theme 2'/>
<input type='button' onclick='theme3();' value='Theme 3'/>
<input type='button' onclick='theme4();' value='Theme 4'/>
</body>
</html>
I'm working with a CMS that prevents us from editing the head section. I need to add css stylesheet to the site, right after the tag. Is there a way to do this with JS, where I can add a script to the bottom of the page (I have access to add script right before the tag) that would then inject the stylesheet into the head section?
Update: According to specs, the link element is not allowed in the body. However, most browsers will still render it just fine. So, to answer the questions in the comments - one really has to add link to the head of the page and not the body.
function addCss(fileName) {
var head = document.head;
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = fileName;
head.appendChild(link);
}
addCss('{my-url}');
Or a little bit easier with jquery
function addCss(fileName) {
var link = $("<link />",{
rel: "stylesheet",
type: "text/css",
href: fileName
})
$('head').append(link);
}
addCss("{my-url}");
Original answer:
You don't need necessarily add it to the head, just add it to the end of body tag.
$('body').append('<link rel="stylesheet" type="text/css" href="{url}">')
as Juan Mendes mentioned, you can insert stylesheet to the head instead
$('head').append('<link rel="stylesheet" type="text/css" href="{url}">')
And the same without jQuery (see code above)
This will do what you want in an intelligent way. Also using pure JS.
function loadStyle(href, callback){
// avoid duplicates
for(var i = 0; i < document.styleSheets.length; i++){
if(document.styleSheets[i].href == href){
return;
}
}
var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = href;
if (callback) { link.onload = function() { callback() } }
head.appendChild(link);
}
I've modified Eddie's function to remove or toggle the stylesheet on or off. It will also return the current state of the stylesheet. This is useful for example, if you want to have a toggle button on your website for vision-impaired users and need to save their preference in a cookie.
function toggleStylesheet( href, onoff ){
var existingNode=0 //get existing stylesheet node if it already exists:
for(var i = 0; i < document.styleSheets.length; i++){
if( document.styleSheets[i].href && document.styleSheets[i].href.indexOf(href)>-1 ) existingNode = document.styleSheets[i].ownerNode
}
if(onoff == undefined) onoff = !existingNode //toggle on or off if undefined
if(onoff){ //TURN ON:
if(existingNode) return onoff //already exists so cancel now
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = href;
document.getElementsByTagName('head')[0].appendChild(link);
}else{ //TURN OFF:
if(existingNode) existingNode.parentNode.removeChild(existingNode)
}
return onoff
}
Sample usage:
toggleStylesheet('myStyle.css') //toggle myStyle.css on or off
toggleStylesheet('myStyle.css',1) //add myStyle.css
toggleStylesheet('myStyle.css',0) //remove myStyle.css
You can use pure javascript and still elegance in the modern browser.
const range = document.createRange()
const frag = range.createContextualFragment(`THE CONTENT IS THE SAME AS THE HTML.`)
document.querySelector("YOUR-NODE").append(frag)
It's very easy to add any HTML code.
Document
createRange
createContextualFragment
Example 1
Add the style on the head by javascript.
<head></head><body><button class="hover-danger">Hello World</button></body>
<script>
const range = document.createRange()
const frag = range.createContextualFragment(`
<style>
.hover-danger:hover{
background-color: red;
font-weight: 900
}
</style>
`
)
document.querySelector("head").append(frag)
</script>
Example 2
Import CSS, JS, and modify the existing stylesheet.
<head></head>
<body><button class="btn btn-primary hover-danger">Hello world</button></body>
<script>
const range = document.createRange()
const frag = range.createContextualFragment(`
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"/>
`)
document.querySelector("head").append(frag)
window.onload = () => {
// 👇 If you don't want to import the new source, you can consider adding the data to exists source.
const nodeLink = document.querySelector(`link[href^="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css"]`) // ^: match begin with my input
if (nodeLink) { // !== null
const stylesheet = nodeLink.sheet
const myCSS = `
background-color:red;
font-weight: 900;
`
stylesheet.insertRule(`.hover-danger:hover{ ${myCSS} }`, stylesheet.cssRules.length)
}
}
</script>
📙 You must have permission to modify the CSS directly
If you get the error:
Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules,
then you can reference: https://stackoverflow.com/a/49994161/9935654
Here is a simple one-liner to add a stylesheet:
document.head.insertAdjacentHTML('beforeend', `<link typs="text/css" rel="stylesheet" href="<Source URL>">`);
I have a javascript function that switch from two different css files that affect my web-site. The problem is that the css are only partially applied with my function and I need to refresh the browser to get the entire new style.
Here is my function:
function switch_style ()
{
var head=document.getElementsByTagName('head')[0];
for (i = 0, link_tag = document.getElementsByTagName("link"); i < link_tag.length ; i++ )
{
if ((link_tag[i].rel.indexOf( "stylesheet" ) != -1) && link_tag[i].title)
{
if (link_tag[i].title == "normal")
{
head.removeChild(link_tag[i]);
}
}
}
var cssNode = document.createElement('link');
cssNode.type = 'text/css';
cssNode.rel = 'stylesheet';
cssNode.href = '/templates/rhuk_milkyway/css/template_contrast.css';
head.appendChild(cssNode);
set_cookie( style_cookie_name, "contrast", style_cookie_duration );
}
As you can see i remove and then append a new style to the page header.
Is there a way to refresh the styling?
(It happens with all browser)
I may be overlooking something, but why do you need to switch stylesheets when you can just add a new class to your html or body element?
Pros:
Faster switching. You do not have to wait until your new css is
loaded - the alternate styles can be included in the original
stylesheet.
Simpler. jQuery.toggleClass (or element.className, if you do not use jQuery) will do all the job.
Works everywhere.
Con(s?):
You have to add the new class to all the selectors in css.
The CSS
<link href="/css/main.css" rel="stylesheet"type="text/css" title="main" media="screen" />
<link href="/css/alt1.css" rel="alternate stylesheet" type="text/css" title="alt1" media="screen" />
The Javascript
function switch_style (title) {
var lnks = document.getElementsByTagName('link');
for (var i = lnks.length - 1; i >= 0; i--) {
if (lnks[i].getAttribute('rel').indexOf('style')> -1 && lnks[i].getAttribute('title')) {
lnks[i].disabled = true;
if (lnks[i].getAttribute('title') == title) lnks[i].disabled = false;
}}}