From e9e959e55d86c0d63c880058eb1af78a7f6e8693 Mon Sep 17 00:00:00 2001 From: Scott Jehl Date: Wed, 29 Nov 2017 15:09:12 -0600 Subject: [PATCH 1/2] shift some internals around to address a timeout problem in the polyfill, and also move the rel attribute change to not block so that IE will continue rendering while the request goes out. fixes #251 --- src/cssrelpreload.js | 55 +++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/src/cssrelpreload.js b/src/cssrelpreload.js index cc5f653..b549f3b 100644 --- a/src/cssrelpreload.js +++ b/src/cssrelpreload.js @@ -13,25 +13,42 @@ // define on the loadCSS obj var rp = loadCSS.relpreload = {}; // rel=preload feature support test - rp.support = function(){ + // runs once and returns a function for compat purposes + rp.support = (function(){ + var ret; try { - return w.document.createElement( "link" ).relList.supports( "preload" ); + ret = w.document.createElement( "link" ).relList.supports( "preload" ); } catch (e) { - return false; + ret = false; } - }; + return function(){ + return ret; + }; + })(); // if preload isn't supported, get an asynchronous load by using a non-matching media attribute // then change that media back to its intended value on load - rp.bindMediaToggle = function( link, media ){ + rp.bindMediaToggle = function( link ){ + // remember existing media attr for ultimate state, or default to 'all' + var finalMedia = link.media || "all"; + function enableStylesheet(){ - link.media = media; + link.media = finalMedia; } + + // bind load handlers to enable media if( link.addEventListener ){ link.addEventListener( "load", enableStylesheet ); } else if( link.attachEvent ){ link.attachEvent( "onload", enableStylesheet ); } + + // Set rel and non-applicable media type to start an async request + // note: timeout allows this to happen async to let rendering continue in IE + setTimeout(function(){ + link.rel = "stylesheet"; + link.media = "only x"; + }); // also enable media after 3 seconds, // which will catch very old browsers (android 2.x, old firefox) that don't support onload on link setTimeout( enableStylesheet, 3000 ); @@ -39,6 +56,7 @@ // loop through link elements in DOM rp.poly = function(){ + // double check this to prevent external calls from running if( rp.support() ){ return; } @@ -47,20 +65,21 @@ var link = links[ i ]; // qualify links to those with rel=preload and as=style attrs if( link.rel === "preload" && link.getAttribute( "as" ) === "style" && !link.getAttribute( "data-loadcss" ) ){ - // remember existing media attr for ultimate state, or default to 'all' - var finalMedia = link.media || "all"; - // bind listeners to toggle media back - rp.bindMediaToggle( link, finalMedia ); - // if preload is not supported, kick off an asynchronous request by using a non-matching media query and rel=stylesheet - link.media = "x"; - link.rel = "stylesheet"; - // prevent rerunning on link link.setAttribute( "data-loadcss", true ); + // bind listeners to toggle media back + rp.bindMediaToggle( link ); } } + }; + + // if unsupported, run the polyfill + if( !rp.support() ){ + // run once at least + rp.poly(); + // rerun poly on an interval until onload - var run = w.setInterval( rp.poly, 300 ); + var run = w.setInterval( rp.poly, 500 ); if( w.addEventListener ){ w.addEventListener( "load", function(){ rp.poly(); @@ -72,9 +91,9 @@ w.clearInterval( run ); } ); } - }; - // run once at least - rp.poly(); + } + + // commonjs if( typeof exports !== "undefined" ){ exports.loadCSS = loadCSS; From e1081d28ed9d423f9f28886e656676935db5e075 Mon Sep 17 00:00:00 2001 From: Scott Jehl Date: Wed, 29 Nov 2017 15:10:43 -0600 Subject: [PATCH 2/2] 2.0.1-0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8a2798e..a2ddc61 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fg-loadcss", - "version": "2.0.0", + "version": "2.0.1-0", "description": "A function for loading CSS asynchronously", "main": "src/loadCSS.js", "repository": {