10

I wonder whether it's possible to change stylesheet link of the loaded document, then wait till the new css is loaded, and then run appropriate js code

thanks for any suggestions

gruber
  • 28,739
  • 35
  • 124
  • 216
  • http://www.w3.org/community/webed/wiki/Dynamic_style_-_manipulating_CSS_with_JavaScript#Accessing_style_sheets – Ana Sep 04 '12 at 22:35

6 Answers6

5

html:

<link id="mystylesheet" href="/path/to/css.css" />

code:

$("#mystylesheet").load(function(){
  //Your javascript
}).attr("href", "/new/path/to/css.css");

This will replace your current CSS, and execute any code within the .load() handler after the new CSS file has been fetched.

ahren
  • 16,803
  • 5
  • 50
  • 70
3

@ahren had it almost correct. However using a callback when the css file is finished loading via dynamically changing the href on a link element DOES NOT seem to work on most mobile devices.

Instead try directly injecting the style into a style element using load .. ends up being supported by most modern browsers including mobile ones

UPDATED to include support for IE 8- ; NOTE this requires you to inject a dummy rule into your css to verify when the css is loaded (in this case use body {ready:true;})

css

body {ready:true;}
...

html

<style id="your-style-element"></style>

javascript

if (document.createStyleSheet) {

    //Wait for style to be loaded
    var wait = setInterval(function(){
      //Check for the style to be applied to the body
      if($('body').css('ready') === 'true') {
        clearInterval(wait);

        //CSS ready
      }
    }, 300);

    document.createStyleSheet(url);
} else {
    //Dynamically load the css for this doc
    $("#your-style-element").load(url,function(){

       //CSS ready
    });
}
Chad Brown
  • 1,627
  • 1
  • 13
  • 22
  • FYI ... just make sure to note that any urls referenced within the css will be relative to the page NOT the location of the css file – Chad Brown Oct 07 '14 at 16:49
  • 1
    does `.load()` fire after the CSS rules are applied? If not, is there a feasible way to do so? – Kragalon Apr 18 '16 at 06:09
  • @Kragalon I bet you could check a specific style attribute (that you know exists in a remote stylesheet) once per frame (using `requestAnimationFrame` in a loop) until the expected value is active. :) – aleclarson Nov 14 '17 at 00:50
0

Try this man: http://forum.jquery.com/topic/loading-stylesheets-on-the-fly

or : http://www.rickardnilsson.net/post/2008/08/02/Applying-stylesheets-dynamically-with-jQuery.aspx or Changing a stylesheet using jQuery

Hope it fits the cause :)

Code

var link = $("<link>");
link.attr({
        type: 'text/css',
        rel: 'stylesheet',
        href: <your CSS file url>
});
$("head").append( link ); 
Community
  • 1
  • 1
Tats_innit
  • 33,991
  • 10
  • 71
  • 77
0

You could try a plug-in I wrote specifically for this case.

Not sure about the .load() method of jQuery, it doesn't seem to be cross-browser. Only IE supports onload="" event on the link elements, afaik.

Jawa
  • 2,336
  • 6
  • 34
  • 39
0

Here's a gist I wrote that works perfect in just 47 LOC:

https://gist.github.com/aleclarson/ac6456c75edae9fe9d9b6938142a065b

It uses requestAnimationFrame to check document.styleSheets on every frame until every given URL fragment has been loaded.

Example:

const styles = require('./styles')
const promise = styles.onLoad('foo.css', 'bar.css')
promise.then(() => console.log('Styles loaded!'))

Pure javascript, too!

aleclarson
  • 18,087
  • 14
  • 64
  • 91
0

TeaCoder has a good answer to this question over at https://stackoverflow.com/a/35644406/20774.

Basically use the elements onload method and put the logic you want to happen after the style loads there.

It's a nice way to use built in DOM capabilities to do it, but the callback syntax is a little awkward. Here is how I did it with Promises:

const createOnLoadPromise = (htmlElement) =>
  new Promise((resolve) => {
    htmlElement.onload = resolve;
  });
const link1 = document.head.appendChild(createStyleLink(href1));
const link2 = document.head.appendChild(createStyleLink(href2));
await Promise.all([
  createOnLoadPromise(link1),
  createOnLoadPromise(link2),
]);
// do whatever you need to do after the await
James McMahon
  • 48,506
  • 64
  • 207
  • 283