Dynamically load css stylesheet and wait for it to load

后端 未结 4 1605
失恋的感觉
失恋的感觉 2020-12-11 03:37

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



        
相关标签:
4条回答
  • 2020-12-11 03:42

    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);
    
    
    0 讨论(0)
  • 2020-12-11 03:44

    To get around race conditions when inserting a style sheet link dynamically and then relying on those calculations:

    function downloadCSS(url) {
        function insertCss(code) {
            var style = document.createElement('style');
            style.type = 'text/css';
            style.innerHTML = code;
            document.querySelector("head").appendChild(style);
        }
    
        return new Promise(async (resolve, reject) => {
            try {
                let src = await axios.get(url);
                insertCss(src.data);
            } catch (e) {
                return reject(e);
            }
    
            requestAnimationFrame(function () {
                resolve();
            });
        });
    }
    
    (async function setup() {
        try {
            await downloadCSS('https://myapp.com/style.css');        
        } catch (e) {
            return reject(e);
        }
        
        //rest of code
    })();
    

    I'm using the axios library for HTTP requests, but you can use anything you like.

    The idea is that you await the downloadCSS promise which downloads the url of your CSS, then inserts the code as a style as opposed to link element, then on the next frame resolves the promise and continues from there.

    0 讨论(0)
  • 2020-12-11 03:45

    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);
    

    jsfiddle

    0 讨论(0)
  • 2020-12-11 04:08

    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
    
    0 讨论(0)
提交回复
热议问题