javascriptcssfirefoxasynchronousfouc

Prevent fouc in firefox and ie


I'm trying to prevent FOUC in FF & IE. Loading my css async, (understandably) causes it. Setting a function to hide and then show the body works on Chrome, but not IE/FF.

I've tried every solution shown online, which are supposed to work and none have. Wondering if there is something being overlooked in my code; or another solution anyone knows?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">


    <title>Web Refinery</title>



    <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico">

    <style>
        .navbar.navbar-default.navbar-fixed-top{border:none;padding-right:2%;font-size:18px;background-color:#000;background-color:rgba(0,0,0,.6);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000);-ms-filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)}ul.navbar-left{color:#000;list-style: outside none none;padding-left:1%;padding-right:1%;margin-top:1%}a.navbar-brand{padding-top:1%;margin-bottom:1%;padding-right:1%}
    </style>



</head>
  <body style="display:none">
    <div class="container-fluid">
     <nav class="navbar navbar-default navbar-fixed-top">
          <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/"><img src="img/logo1-min.png"></a>     
          </div>

         <div class="collapse navbar-collapse" id="myNavbar">
            <ul class="navbar-left">
            <li type="none" class="hover descript">Design & Development</li> 
            </ul>  
            <ul class="nav navbar-nav navbar-right">
                <li class="hover"><a href="portfolio.html">Portfolio<span class="sr-only"></span></a></li>
                <li class="hover"><a href="services.html">Services</a></li>
            <li class="hover"><a href="contact.html">Contact<span class="sr-only"></span></a></li>
            </ul>
        </div><!-- /.navbar-collapse -->
      </nav>
      <div class="row text-center headDrop">
        <div class="col-md-1"></div>  
        <div class="col-md-10">
          <h1>WEB REFINERY</h1>
          <h2>Responsive Design & Development</h2>
        </div>
        <div class="col-md-1"></div>  
          <br>
        </div>  
        <div class="row text-center">
            <div class="col-md-1"></div>
            <div class="col-md-10">
                <br>

                <p>Metro Milwaukee - Design Studio</p>
                <p>Web Design - Development - Branding</p>
            </div>
            <div class="col-md-1"></div>
        </div>  
    </div>

        <script type="text/javascript">
        /* Beginning of async download code. */
        window.onload = function(){

            function loadjscssfile(filename, filetype) {
                if(filetype == "js") {
                    var cssNode = document.createElement('script');
                    cssNode.setAttribute("type", "text/javascript");
                    cssNode.setAttribute("src", filename);
                } else if(filetype == "css") {
                    var cssNode = document.createElement("link");
                    cssNode.setAttribute("rel", "stylesheet");
                    cssNode.setAttribute("type", "text/css");
                    cssNode.setAttribute("href", filename);
                }
                if(typeof cssNode != "undefined")
                    document.getElementsByTagName("head")[0].appendChild(cssNode);
            }
            loadjscssfile("//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css", "css");
            loadjscssfile("/css/main-min.css", "css");

            loadjscssfile("//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js", "js");
            loadjscssfile("//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js", "js");
            loadjscssfile("/js/main-min.js", "js");



        };
        /* End of async download code. */

        document.onreadystatechange = function () {
                var view = document.getElementsByTagName('body')[0];
                  if (document.readyState == "complete") {
                      view.style.removeProperty('display');
                  } else {}

        };


    </script>   

  </body>

</html>

Solution

  • I would remove the display:none style once all the CSS has finished loading, like this

    window.onload = function(){
        var resources = [
            { url: "//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css", type: "css"},
            { url: "/css/main-min.css", type: "css"},
    
            { url: "//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js", type: "js"},
            { url: "//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js", type: "js"},
            { url: "/js/main-min.js", type: "js"}
        ];
        var head = document.getElementsByTagName("head")[0];
        var cssToLoad = 0;
        var loadOrError = function (e) {
            cssToLoad -= 1;
            if (cssToLoad < 0) { // prevent early trigger
                document.body.style.removeProperty('display');
            }
        };
        resource.forEach(function(resource) {
            var element;
    
            if (resource.type == "js") {
                element = document.createElement('script');
                element.setAttribute("type", "text/javascript");
                element.setAttribute("src", resource.url);
            } else if (resource.type == "css") {
                cssToLoad += 1;
                element = document.createElement("link");
                element.setAttribute("rel", "stylesheet");
                element.setAttribute("type", "text/css");
                element.setAttribute("href", resource.url);
                element.addEventListener('load', loadOrError);
                element.addEventListener('error', loadOrError);
            }
            if (typeof element != "undefined") {
                head.appendChild(element);
            }
        });
        loadOrError(); // end prevent early trigger
    };