Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically load css stylesheet and wait for it to load

I have a script that detects a button click on which it will attach a CSS stylesheet to the "head" with jQuery like so:

const link = "<link class='listcss' rel='stylesheet' href='http://....list.css'>";
$("head").append(link);

Then I need to do some calculations based on the css width and height properties:

function CSSDone(){
            if($(window).width()>640){
                $(".grid-item").css({"height":$(".grid-item").width()*0.2});
                $(".grid_item_img").css({"height":$(".grid-item").width()*0.2});
            console.log("a");
            }else{
                $(".grid-item").css({"height":$(".grid-item").width()*0.33});
                $(".grid_item_img").css({"height":$(".grid-item").width()*0.33});
            console.log("b");       
            }
        }
        CSSDone();

However, if I launch CSSDone(); right after adding the stylesheet, the calculations happen before the css is loaded. I searched the web like crazy but everything I tried doesn't work:

I tried these options:

  1. Does not work:

    link.onload = function () { CSSDone(); }

  2. Does not work:

     if (link.addEventListener) {
       link.addEventListener('load', function() {
         CSSDone();
       }, false);
     }
    
  3. Does not work:

     link.onreadystatechange = function() {
       var state = link.readyState;
       if (state === 'loaded' || state === 'complete') {
         link.onreadystatechange = null;
         CSSDone();
       }
     };
    
  4. Does not work:

     $(window).load(function () {
         CSSDone();
     });
    
  5. Does not work:

     $(window).bind("load", function() {
         CSSDone();
     });
    

Believe me. Nothing works......


**One workaround:**

I load the css in the DOM and immidiately remove it again with jQuery. That way when adding the link to the head later it's fast enough.

like image 690
mesqueeb Avatar asked Feb 26 '16 05:02

mesqueeb


People also ask

How do I load dynamic CSS?

Load CSS and JS files dynamically: We create a script element for the JS file and link element for the CSS file as required using DOM, assign the appropriate attributes to them, and then add the element to the desired location within the document tree using the element. append() method.

How do I load a CSS file dynamically in React JS?

To dynamically load a stylesheet with React, we can add a link element with the attributes we want. to create the stylePath state with the useState hook. Its initial value is set to the URL of the stylesheet that we want to include.


3 Answers

You need to insert a link node in the head and then attach onload event to that. In your code link is a String. See sample code below on how to implement what you want.

var link = document.createElement('link');
link.setAttribute("rel", "stylesheet");
link.setAttribute("type", "text/css");
link.onload = CSSDone;
link.setAttribute("href", 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css');
document.getElementsByTagName("head")[0].appendChild(link);

Check jsfiddle.

MDN reference on Link element in case you are curious

like image 61
TeaCoder Avatar answered Oct 24 '22 05:10

TeaCoder


You can try this i believe.. include the CSSDone() code in $("head").append(link)'s callback

$(document).ready(function(){
$('.btn').on('click', function(){
link = "<link class='listcss' rel='stylesheet' href='/list.css'>";
        $("head").append(link, function(){
        if($(window).width()>640){
                $(".grid-item").css({"height":$(".grid-item").width()*0.2});
                $(".grid_item_img").css({"height":$(".grid-item").width()*0.2});
            console.log("a");
            }else{
                $(".grid-item").css({"height":$(".grid-item").width()*0.33});
                $(".grid_item_img").css({"height":$(".grid-item").width()*0.33});
            console.log("b");       
            }

        }); // append link

        }); // button click
}); // document ready
like image 31
RRR Avatar answered Oct 24 '22 06:10

RRR


Using jQuery:

var head = $('head');
var link = $('<link>')
    .attr('rel', 'stylesheet')
    .attr('type', 'text/css')
    .attr('href', url)
                        .on('load', callback)
                        .on('error', error)
                       .appendTo(head);

like image 1
user3707531 Avatar answered Oct 24 '22 04:10

user3707531