How can I set the location of a stylesheet with jQuery?
You can manipulate the <head> element in much the same way that you can elements inside the <body> tag:
$("head>link[href$=mystyle.css]").remove();
$('<link rel="stylesheet" href="/css/anotherstyle.css"/>').appendTo("head");
This removes the mystyle.css <link> tag and insert a new <link> tag with /css/anotherstyle.css at the end of the <head> element.
One approach is to give the <link> element an ID and use that as your selector, changing the href property on the matching element:
$("#myStyle")[0].href = "/path/to/new.css";
Another approach is to have multiple style sheets attached to your document and enable/disable them when necessary:
<link id="style1" href="style1.css" />
<link id="style2" href="style2.css" disabled="disabled" />
$("#style1").attr("disabled", true).next().attr("disabled", false);
This approach is best when regularly switching all the styles for your page.
Related
I have a page which has <link> in the header that loads the CSS named light.css. I also have a file named dark.css. I want a button to swap the style of the page all together (there are 40 selectors used in css file and some do not match in two files).
How can I remove reference to light.css with JS and remove all the styles that were applied and then load dark.css and apply all the styles from that? I can't simply reset all of the elements, since some of the styles are applied through different css files and some are dynamically generated by JS. Is there a simple, yet effective way to do that without reloading the page? Vanilla JS is preferable, however I will use jQuery for later processing anyways, so jQ is also fine.
You can include all the stylesheets in the document and then activate/deactivate them as needed.
In my reading of the spec, you should be able to activate an alternate stylesheet by changing its disabled property from true to false, but only Firefox seems to do this correctly.
So I think you have a few options:
Toggle rel=alternate
<link rel="stylesheet" href="main.css">
<link rel="stylesheet alternate" href="light.css" id="light" title="Light">
<link rel="stylesheet alternate" href="dark.css" id="dark" title="Dark">
<script>
function enableStylesheet (node) {
node.rel = 'stylesheet';
}
function disableStylesheet (node) {
node.rel = 'alternate stylesheet';
}
</script>
Set and toggle disabled
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="light.css" id="light" class="alternate">
<link rel="stylesheet" href="dark.css" id="dark" class="alternate">
<script>
function enableStylesheet (node) {
node.disabled = false;
}
function disableStylesheet (node) {
node.disabled = true;
}
document
.querySelectorAll('link[rel=stylesheet].alternate')
.forEach(disableStylesheet);
</script>
Toggle media=none
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="light.css" media="none" id="light">
<link rel="stylesheet" href="dark.css" media="none" id="dark">
<script>
function enableStylesheet (node) {
node.media = '';
}
function disableStylesheet (node) {
node.media = 'none';
}
</script>
You can select a stylesheet node with getElementById, querySelector, etc.
(Avoid the nonstandard <link disabled>. Setting HTMLLinkElement#disabled is fine though.)
You can create a new link, and replace the old one with the new one. If you put it in a function, you can reuse it wherever it's needed.
The Javascript:
function changeCSS(cssFile, cssLinkIndex) {
var oldlink = document.getElementsByTagName("link").item(cssLinkIndex);
var newlink = document.createElement("link");
newlink.setAttribute("rel", "stylesheet");
newlink.setAttribute("type", "text/css");
newlink.setAttribute("href", cssFile);
document.getElementsByTagName("head").item(cssLinkIndex).replaceChild(newlink, oldlink);
}
The HTML:
<html>
<head>
<title>Changing CSS</title>
<link rel="stylesheet" type="text/css" href="positive.css"/>
</head>
<body>
STYLE 1
STYLE 2
</body>
</html>
For simplicity, I used inline javascript. In production you would want to use unobtrusive event listeners.
If you set an ID on the link element
<link rel="stylesheet" id="stylesheet" href="stylesheet1.css"/>
you can target it with Javascript
document.getElementsByTagName('head')[0].getElementById('stylesheet').href='stylesheet2.css';
or just..
document.getElementById('stylesheet').href='stylesheet2.css';
Here's a more thorough example:
<head>
<script>
function setStyleSheet(url){
var stylesheet = document.getElementById("stylesheet");
stylesheet.setAttribute('href', url);
}
</script>
<link id="stylesheet" rel="stylesheet" type="text/css" href="stylesheet1.css"/>
</head>
<body>
<a onclick="setStyleSheet('stylesheet1.css')" href="#">Style 1</a>
<a onclick="setStyleSheet('stylesheet2.css')" href="#">Style 2</a>
</body>
This question is pretty old but I would suggest an approach which is not mentioned here, in which you will include both the CSS files in the HTML, but the CSS will be like
light.css
/*** light.css ***/
p.main{
color: #222;
}
/*** other light CSS ***/
and dark.css will be like
/*** dark.css ***/
.dark_theme p.main{
color: #fff;
background-color: #222;
}
/*** other dark CSS ***/
basicall every selector in dark.css will be a child of .dark_theme
Then all you need to do is to change the class of body element if someone selects to change the theme of the website.
$("#changetheme").click(function(){
$("body").toggleClass("dark_theme");
});
And now all your elements will have the dark css once the user clicks on #changetheme. This is very easy to do if you are using any kind of CSS preprocessors.
You can also add CSS animations for backgrounds and colors which makes the transition highly smooth.
Using jquery you can definitely swap the css file. Do this on button click.
var cssLink = $('link[href*="light.css"]');
cssLink.replaceWith('<link href="dark.css" type="text/css" rel="stylesheet">');
Or as sam's answer, that works too. Here is the jquery syntax.
$('link[href*="light.css"]').prop('disabled', true);
$('link[href*="dark.css"]').prop('disabled', false);
Using jquery .attr() you can set href of your link tag .i.e
Sample code
$("#yourButtonId").on('click',function(){
$("link").attr(href,yourCssUrl);
});
Maybe I'm thinking too complicated, but since the accepted answer was not working for me I thought I'd share my solution as well.
Story:
What I wanted to do was to include different 'skins' of my page in the head as additional stylesheets that where added to the 'main' style and switch them by pressing a button on the page (no browser settings or stuff).
Problem:
I thought #sam's solution was very elegant but it did not work at all for me. At least part of the problem is that I'm using one main CSS file and just add others on top as 'skins' and thus I had to group the files with the missing 'title' property.
Here is what I came up with.
First add all 'skins' to the head using 'alternate':
<link rel="stylesheet" href="css/main.css" title='main'>
<link rel="stylesheet alternate" href="css/skin1.css" class='style-skin' title=''>
<link rel="stylesheet alternate" href="css/skin2.css" class='style-skin' title=''>
<link rel="stylesheet alternate" href="css/skin3.css" class='style-skin' title=''>
Note that I gave the main CSS file the title='main' and all others have a class='style-skin' and no title.
To switch the skins I'm using jQuery. I leave it up to the purists to find an elegant VanillaJS version:
var activeSkin = 0;
$('#myButton').on('click', function(){
var skins = $('.style-skin');
if (activeSkin > skins.length) activeSkin=0;
skins.each(function(index){
if (index === activeSkin){
$(this).prop('title', 'main');
$(this).prop('disabled', false);
}else{
$(this).prop('title', '');
$(this).prop('disabled', true);
}
});
activeSkin++
});
What it does is it iterates over all available skins, takes the (soon) active one, sets the title to 'main' and activates it. All other skins are disabled and title is removed.
Simply update you Link href attribute to your new css file.
function setStyleSheet(fileName){
document.getElementById("WhatEverYouAssignIdToStyleSheet").setAttribute('href', fileName);
}
I reworked lampe's example, and you can add a class using a selector in this way:
first apply the class to specific selectors in a javascript (repeat as many times you need for specific element selectors (in my HTML):
$("p:nth-of-type(even)").toggleClass("main mainswitch");
Then the html looks like this
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js">
</script>
<script>
$(document).ready(function(){
$("button").click(function(){
$(".mainswitch").toggleClass("main");
});
});
</script>
<style>
.main {
font-size: 120%;
color: red;
}
</style>
</head>
<body>
<div>
<p>This is a paragraph.</p>
<p class="main mainswitch">This is another paragraph.</p>
<p>This is a paragraph.</p>
<p>This is a paragraph.</p>
<p>This is a paragraph.</p>
</div>
<button>Toggle class "main" for p elements</button>
</body>
</html>
If you're using Angular (cause it's not 2013 anymore), you can try the answer/solution/suggestion from here:
How can I change the targeted CSS file on a click event
It did the trick for me.
I am trying to disable two css links from my page which are linked using Link tag.
<div class="ExportedContent">
<link href="//thisismysite/common14/css/bootstrap.min.css" rel="stylesheet" media="screen">
<link rel="stylesheet" href="//thisismysite/common14/stylesheet_2014.css" type="text/css">
</div>
I have following code to remove this link which is not working
<script>
$(document).ready(function(){
$('link[href="https://grants.nih.gov/common14/css/bootstrap.min.css"]').remove();
$('link[href="https://grants.nih.gov/common14/stylesheet_2014.css"]').remove();
});
</script>
So far this is not working any ideas
link elements at html and selector at js appear to have different href attribute values ?
Try using attribute ends with selector , .removeAttr()
$("link[href$='bootstrap.min.css'], link[href$='stylesheet_2014.css']")
.removeAttr("href")
Your links starts with //domain
and your selector starts with https://domain
That is a non match
What you could do is using [name$=”value”] selector that match something that ends with a given string. This comparison is case sensitive.
Another thing you could work with instead of removing the link tag is document.styleSheets
And may i say that it looks odd that the link tags are inside a div tag...
document.styleSheets[0].disabled = true
I'm looking at a site template.
I find that when the user clicks on a link, it runs a JavaScript with this command to change the site theme:
$('link#theme').attr('href', 'theme2.css');
In jQuery what does this selector mean? What object this command change in my page?
This selects a link element, with the theme id, which is a link to a CSS style sheet.
The attr changes the href, so that it points to a differnt style sheet, forcing the browser to load a new style sheet.
Remember that to include an style sheet to a page you need to use this element:
<link rel="stylesheet" type="text/css" href="theme1.css">
You can add an id so that the selector finds it, and can manipulate it:
<link rel="stylesheet" type="text/css" href="theme1.css" id="theme">
Is it possible to expand existing html tag?
For example i want add type of <link> tag and make some action on this type
<link rel="stylesheet" type="new-type" href="theme.css">
and when we have link with new type make some action automatically?
Yes, you can. The best to do this is to use the data- attributes. Those are skipped by any validator so safe to use for your own purpose:
<link id="someId" rel="stylesheet" type="new-type" href="theme.css" data-special="true">
If you use jQuery, you can even get it out easy:
var x = $("#someId").data("special");
You can use insertAdjacentHTML. In the example below the new element will be inserted after the element defined by `getElementById("link"):
var element = document.getElementById("link");
var newElement = '<link rel="stylesheet" type="new-type" href="theme.css">'
element.insertAdjacentHTML( 'afterend', newElement )
See this link for the full documentation: https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML
yes you can. you have to do a simple modification to your code like below-
<link rel="stylesheet" data-type="new-type" href="theme.css">
Trying to replace the conents of a whole page ( works ) + also replace the link to a style.css to game.css, with query
$.get('/games/14', function(data){ var $page = $(data);
$('head').append('<link rel="stylesheet" href="style2.css" type="text/css" />');
//$('#layout').empty().append($page);
$('body').empty().append($page);
})
I seem to be unable to change the "style.css" to "game.css" no matter what I try, wich Jquery Guru knows how to accomplish this? thx !
UPDATE:
tried the suggestions below still have issues, this is what I'm using now ( no replacement of the .css file )
$.get('/games/14', function(data){
$("link[href='style.css']").attr({href: 'game.css'});
var $page = $(data);
$('body').empty().append($page);
})
Here ya go, just tested this out and it worked.
<!DOCTYPE HTML>
<html>
<head>
<script src="jquery-1.7.2.min.js"></script>
<link href="/assets/frontend.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
<script>
$("link[href='/assets/frontend.css']").attr('href', '/assets/game.css');
</script>
</body>
</html>
To anwer your comment below, I tested it using Firebug.
Using the Console tab, I can see that it first attempted to load up assets/frontend.css, ran the JS, then attempted to load up assets/game.css.
I then checked the DOM in the HTML tab of firebug, and saw that the link elements href attribute was updated.
Target the link element with href attribute 'style.css' and replace the href attribute of that element with 'game.css':
$("link[href='style.css']").attr({href: 'game.css'});
You can use jQuery's attr() function to change the href.
$("link[href=style.css]").attr('href', 'game.css');
There's probably a more rock-solid selector you'll want to use, but that'll do it.
href attribute substitution as suggested in other answers is inconsistently handled by different browsers (i.e. may not trigger re-flow/re-render). Instead, the original style element has to be removed and a new element with the desired href has to be inserted in its place. An intuitive way to do so with jQuery:
$('link[href$="style.css"]').replaceWith('<link href="game.css" ... ></link>');