Dynamically loading css stylesheet doesn't work on IE - javascript

I dynamically load a css stylesheet (with a little help from jQuery) like this:
var head = document.getElementsByTagName('head')[0];
$(document.createElement('link'))
.attr({ type: 'text/css', href: '../../mz/mz.css', rel: 'stylesheet' })
.appendTo(head);
This works fine in Firefox and Google Chrome, but not in IE.
Any help?
Thanks

Once IE has processed all the styles loaded with the page, the only reliable way to add another stylesheet is with document.createStyleSheet(url)
See the MSDN article on createStyleSheet for a few more details.
url = 'style.css';
if (document.createStyleSheet)
{
document.createStyleSheet(url);
}
else
{
$('<link rel="stylesheet" type="text/css" href="' + url + '" />').appendTo('head');
}

You need to set the href attr last and only after the link elem is appended to the head:
$('<link>')
.appendTo('head')
.attr({type : 'text/css', rel : 'stylesheet'})
.attr('href', '/css/your_css_file.css');
Update
Nowadays the only purpose of IE and Edge is to download Chrome, so I recommend NOT bloating your code with custom support for IE or Edge and rather just ignoring their existence.

This also seems to work in IE:
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = '/includes/style.css';
document.getElementsByTagName('head')[0].appendChild(link);

This might also have something to do with it - Taken from Microsoft Support article:
Styles on a webpage are missing or look incorrect when the page loads in the versions of Microsoft Internet Explorer
...
...This problem occurs because the
following conditions are true in
Internet Explorer:
All style tags
after the first 31 style tags are not
applied.
All style rules after the
first 4,095 rules are not applied.
On
pages that uses the #import rule to
continously import external style
sheets that import other style sheets,
style sheets that are more than three
levels deep are ignored.

It seems that
$('<link rel="stylesheet" type="text/css" href="' + url + '" />').appendTo('head');
works also in IE as long as the url is a fully qualified URI including the protocol...

Open ie8 without the debugger open. When you get to after the point of dynamic stylesheet... open the debugger and voila, they should be there.

Related

Adding a stylesheet dynamically

After the document.ready event fires, I load the stylesheet dynamically based on the user's resolution. This is what works in Chrome, Firefox and IE:
var TheFileName = '/SomeDirectory/SomeFileName.css';
if (document.createStyleSheet) {
//finally found something IE got right
document.createStyleSheet(TheFileName);
} else {
$('<style id="TestCSS" type="text/css"></style>').appendTo('head');
$.get(TheFileName , function (TheCSS) {
$("#TestCSS").append(TheCSS);
});
}
The problem is that it doesn't work in Safari. I don't have a mac so I don't have the console error but all I know is that the stylesheet doesn't get added. What do I need to change to make it work in Safari?
PS: I don't want to use media queries.
Edit
I initially had a function that used a <link> tag that was added. My page is entirely dynamically generated and the problem is that adding the stylesheet after the DOM is rendered makes the elements unstyled if you use a <link> tag. So what I do is use a setTimeout to check for $('#TestCSS').length to see if the stylesheet loaded and then I fire the functions that create the HTML. With a tag, there's no way of knowing when the CSS is attached.
Why not just insert the stylesheet as a link tag, instead of loading it with ajax, should be cross-browser ?
var link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.type = 'text/css';
link.href = '/SomeDirectory/SomeFileName.css';
document.head.appendChild(link);

Inject css to page without using onload (IE)?

I've written a widget which relies on having to inject a css file onto the html page.
I am using the following code to inject the css-sheet:
var link = document.createElement("link");
link.href = "http://myurl.com/style.css";
link.rel = "stylesheet";
document.body.appendChild(link);
This works in all browsers except for IE, for this to work in IE i have to do a:
window.onload
Like this:
window.onload=function() {
//inject here
}
I want to find a way to accomplish this without having to use window.onload, since window.onload only loads my widget when all of the pages has loaded, for bigger pages it takes forever to load the widget.. Is there any workaround for this?
I am assuming the this script is in the body. Append it to the head and not the body
document.getElementsByTagName("head")[0].appendChild(link);

Using Javascript to detect if font is installed, then serve different css if it's not

I'm new to Javascript (but not HTML or CSS) and am trying to use this script by Lalit Patel to detect whether a font is installed on the user's system, and if not, to serve a modified style sheet. I've been successful in getting the first part to work: I uploaded the fontdetect.js file, called it in my header, then pasted this before the end of my body tag:
<script type="text/javascript">
window.onload = function() {
var detective = new Detector();
alert(detective.detect('Courier'));
};
</script>
(With Courier used as an example.) This causes an alert to pop up on page load telling me whether a font is installed, and works beautifully. But I don't know how to get the script to, instead of triggering an alert, grab a different stylesheet. This seems like basic stuff but I just can't find the specifics anywhere, even though I've been plowing through Javascript tutorials. Any guidance would be greatly appreciated!
If any more specifics are needed: If a user doesn't have the custom font installed or has custom fonts turned off entirely, I'd like to, using CSS change the size/spacing properties of the text so that the fallback font is able to fit in the same space.
var detective = new Detector();
if (!detective.detect('Courier')){
var s = document.createElement('link');
s.rel = 'stylesheet';
s.type = 'text/css';
s.media = 'all';
s.href = '/link/to/alternative/stylesheet.css';
document.getElementsByTagName('head')[0].appendChild(s);
}
Guessing something like that. if .detect() fails, it will dynamically create and insert a stylesheet in to the page. If you encounter problems, you can also use .setAttribute() off of the s element.
You can use JS to add a stylesheet to the website:
var detective = new Detector();
if (!detective.detect('Courier')){
document.createStyleSheet('location/stylesheet.css');
}
else
{
document.createStyleSheet('location/otherstylesheet.css');
}
So you could do a check to see if the Dectector returns true, if not load one style, if it does then load the other.
After trying all the methods presented, this is the one that worked for me (from this answer, but it's really a mix of the two answers presented here). It should be noted that this works in IE8, unlike most of the other methods (sadly I do need IE8 compatibility).
<script type="text/javascript">
window.onload = function() {
var detective = new Detector();
if (!detective.detect('Meat')){
var url = 'link/to/style.css'
if(document.createStyleSheet) {
try { document.createStyleSheet(url); } catch (e) { }
}
else {
var css;
css = document.createElement('link');
css.rel = 'stylesheet';
css.type = 'text/css';
css.media = "all";
css.href = url;
document.getElementsByTagName("head")[0].appendChild(css);
}
}
};
</script>
This detected that my browser wasn't accepting embedded fonts ("Meat" being one of the fonts I embedded) and served up the alternate CSS (although with a slight delay/flash of unstyled text, maybe because it's at the bottom of the page?) Anyhow, thanks again for all the help!

CSS style refresh in IE after dynamic removal of style link

I've got a problem with the dynamic style manipulation in IE7 (IE8 is fine). Using javascript I need to add and remove the < link /> node with the definition of css file.
Adding and removing the node as a child of < head /> works fine under Firefox. Unfortunately, after removing it in the IE, although The tag is removed properly, the page style does not refresh.
In the example below a simple css (makes background green) is appended and removed. After the removal in FF the background turns default, but in IE stays green.
index.html
<html>
<head>
</head>
<script language="javascript" type="text/javascript">
var node;
function append(){
var headID = document.getElementsByTagName("head")[0];
node = document.createElement('link');
node.type = 'text/css';
node.rel = 'stylesheet';
node.href = "s.css";
node.media = 'screen';
headID.appendChild(node);
}
function remove(){
var headID = document.getElementsByTagName("head")[0];
headID.removeChild(node);
}
</script>
<body>
<div onClick="append();">
add
</div>
<div onClick="remove();">
remove
</div>
</body>
</html>
And the style sheet:
s.css
body { background-color:#00CC33 }
Here is the live example: http://rlab.pl/dynamic-style/
Is there a way to get it working?
Rybz, I, personally, would setup an "initial" style sheet to reset back to (also because it helps reset browsers to "my" desired initial settings, not the browser defaults) and when removing the style sheet from the DOM I would insert the one to reset to. I don't know if this will work for what you are trying to do, but it worked for me in the similar situation, and if I remember correctly I was having the same problem as you do, and that fixed it.

Dynamically changing stylesheet path not working in IE and Firefox

I have the following file:
<html>
<head>
<title></title>
<link rel="css" type="text/css" href="/empty.css" title="css" />
<script type="text/javascript" src="/Prototype"></script>
<script type="text/javascript">
function load_content()
{
var d = new Date();
new Ajax.PeriodicalUpdater('content', '/DOC?'+d.getTime(),
{
method: 'post',
frequency: 5,
onSuccess: function(transport) {
for(i=0; (a = document.getElementsByTagName('link')[i]); i++)
{
if(a.getAttribute('rel') == 'css' && a.getAttribute("type") == 'text/css')
{
a.href = '/CSS?'+d.getTime();
}
}
}
});
}
</script>
</head>
<body>
<div id="content"></div>
<script type="text/javascript">
load_content();
</script>
</body>
</html>
Note: Ignore the d.getTime() calls...these are just to get around an issue with IE not loading a new page from an AJAX call because it's caching scheme is too aggressive.
Basically, when it reloads the file at /DOC, it is supposed to be setting the current stylesheet to the file at /CSS... both DOC and CSS and constantly changing.
What's weird is that in Chrome it works great. DOC loads up in the "content" div and the stylesheet gets set to CSS and that css is applied to the page. I can change with CSS page and withing 5 seconds, when the page is refreshed, the CSS will be refreshed as well.
But in IE and Firefox, the HTML will load and I can see that the href attribute of the stylesheet link IS getting changed to "/CSS + getTime()" but, while the HTML loads, the css is never applied to the page. I can even change the content of DOC and it updates, but the css is never even applied. It just stays a style-free page.
Does Firefox and IE not support changing the style sheet reference in this way?
Is there a better way to do this?
Rather than changing the sheet in a single link, try using alternate style sheets. See this link on using alternate style sheets:
http://www.alistapart.com/articles/alternate/
The best way to include files via javascript is to insert a new dom element.
var a = document.createElement('link');
a.href="inset.css";
a.rel="stylesheet";
document.getElementsByTagName("head")[0].appendChild(a);
However, obviously the problem you're going to run into though is that firefox and ie will not repaint the canvas once the document is finished loading (and you're using ajax). The way you get around that is by taking the contents of the stylesheets and including them in a style element. This sample code will change the color on the page dynamically.
function onLoadFunction() {
var a = document.createElement('style');
a.appendChild(document.createTextNode('body {color: blue;}'));
document.getElementsByTagName("body")[0].appendChild(a);
}
When you load a new sheet, just destroy the css inside the style element and replace it.
maybe this will help you ...
http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
function loadjscssfile(filename, filetype){
if (filetype=="js"){ //if filename is a external JavaScript file
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
}
else if (filetype=="css"){ //if filename is an external CSS file
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref)
}
It looks like you are simply reloading the existing page every time. Why not just use the refresh tag in your header to force the document to reload each time and put in the CSS and content server-side. A lot simpler and it works even with javascript disabled.
<meta http-equiv="refresh" content="5;url=http://example.com/DOC" />
It might be a caching issue. If you do a hard refresh (Ctrl+R in FF, Ctrl+F5 in IE) does it display the style properly? If that does fix it, you may want to look at removing the Last-Modified header from the CSS file or adding a cache control header telling the browser not to cache it.

Categories

Resources