Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the link element's onload attribute unreliable for android stock browsers?

       var style1 = document.createElement("link");
       style1.id = "rel";
       style1.rel = "stylesheet";
       style1.href = "http://www.mysite.com/css.css";
       style1.onload = function(){document.body.innerHTML+="fffffff";};
       document.getElementsByTagName("head")[0].appendChild(style1);

This code works in Chrome/Firefox, and yet stock browsers on my Froyo (2.3) and Jellybean (4.1) Android devices will print nothing. What's the problem? I'd like if I could execute some js onload of a link. Anything else would in my case amount to a hack. :/

The problem isn't innerHTML. Try it with alerts if you want (at your own peril).

Another answer mentions checking for this functionality by doing

var huh = 'onload' in document.createElement('link');

..but this is true in both stock browsers! wtf guys?

like image 222
Amalgovinus Avatar asked Dec 19 '12 02:12

Amalgovinus


1 Answers

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

like image 84
Serg Hospodarets Avatar answered Oct 24 '22 08:10

Serg Hospodarets