[removed] capturing load event on LINK

后端 未结 9 1296
没有蜡笔的小新
没有蜡笔的小新 2020-11-29 01:00

i\'m trying to attach an event handler to the load event of a link tag, to execute some code after a stylesheet has loaded.

new_element = document.createElem         


        
相关标签:
9条回答
  • 2020-11-29 01:55

    An href does not have a load event you need to apply your stuff as the page itself loads e.g.

    window.onload = function(){
    //code here
    
    }
    

    use the function on this page: http://www.dustindiaz.com/top-ten-javascript/

    to add the event the body element (in line would be )

    0 讨论(0)
  • 2020-11-29 01:57

    E.g. Android browser doesn't support "onload" / "onreadystatechange" events for element: http://pieisgood.org/test/script-link-events/
    But it returns:

    "onload" in link === true
    

    So, my solution is to detect Android browser from userAgent and then wait for some special css rule in your stylesheet (e.g., reset for "body" margins).
    If it's not Android browser and it supports "onload" event- we will use it:

    var userAgent = navigator.userAgent,
        iChromeBrowser = /CriOS|Chrome/.test(userAgent),
        isAndroidBrowser = /Mozilla\/5.0/.test(userAgent) && /Android/.test(userAgent) && /AppleWebKit/.test(userAgent) && !iChromeBrowser; 
    
    addCssLink('PATH/NAME.css', function(){
        console.log('css is loaded');
    });
    
    function addCssLink(href, onload) {
        var css = document.createElement("link");
        css.setAttribute("rel", "stylesheet");
        css.setAttribute("type", "text/css");
        css.setAttribute("href", href);
        document.head.appendChild(css);
        if (onload) {
            if (isAndroidBrowser || !("onload" in css)) {
                waitForCss({
                    success: onload
                });
            } else {
                css.onload = onload;
            }
        }
    }
    
    // We will check for css reset for "body" element- if success-> than css is loaded
    function waitForCss(params) {
        var maxWaitTime = 1000,
            stepTime = 50,
            alreadyWaitedTime = 0;
    
        function nextStep() {
            var startTime = +new Date(),
                endTime;
    
            setTimeout(function () {
                endTime = +new Date();
                alreadyWaitedTime += (endTime - startTime);
                if (alreadyWaitedTime >= maxWaitTime) {
                    params.fail && params.fail();
                } else {
                    // check for style- if no- revoke timer
                    if (window.getComputedStyle(document.body).marginTop === '0px') {
                        params.success();
                    } else {
                        nextStep();
                    }
                }
            }, stepTime);
        }
    
        nextStep();
    }
    

    Demo: http://codepen.io/malyw/pen/AuCtH

    0 讨论(0)
  • 2020-11-29 02:03

    All credit goes to Tobiasz up above, but here's a little expansion on what he said:

    function _cssIsLoaded(cssStylesheet) {
        var cssLoaded = 0;
        try {
            if ( cssStylesheet.sheet && cssStylesheet.sheet.cssRules.length > 0 )
                cssLoaded = 1;
            else if ( cssStylesheet.styleSheet && cssStylesheet.styleSheet.cssText.length > 0 )
                cssLoaded = 1;
            else if ( cssStylesheet.innerHTML && cssStylesheet.innerHTML.length > 0 )
                cssLoaded = 1;
            }
            catch(ex){ }
    
            if(cssLoaded) {
                // your css is loaded! Do work!
                // I'd recommend having listeners subscribe to cssLoaded event, 
                // and then here you can emit the event (ie. EventManager.emit('cssLoaded');
            } else {
                // I'm using underscore library, but setTimeout would work too
                // You basically just need to call the function again in say, 50 ms
                _.delay(_.bind(this._cssIsLoaded, this), 50, cssStylesheet);
            }
    }
    

    You'd call it with something like (using jquery):

    var link = $("<link>");
    link.attr({
        type: 'text/css',
        rel: 'stylesheet',
        href: sheet
    });
    
    $("head").append(link);
    // link.get(0), because you want the actual element, not jQuery-wrapped element
    self._cssIsLoaded(link.get(0));
    
    0 讨论(0)
提交回复
热议问题