|
13 | 13 | // define on the loadCSS obj |
14 | 14 | var rp = loadCSS.relpreload = {}; |
15 | 15 | // rel=preload feature support test |
16 | | - rp.support = function(){ |
| 16 | + // runs once and returns a function for compat purposes |
| 17 | + rp.support = (function(){ |
| 18 | + var ret; |
17 | 19 | try { |
18 | | - return w.document.createElement( "link" ).relList.supports( "preload" ); |
| 20 | + ret = w.document.createElement( "link" ).relList.supports( "preload" ); |
19 | 21 | } catch (e) { |
20 | | - return false; |
| 22 | + ret = false; |
21 | 23 | } |
22 | | - }; |
| 24 | + return function(){ |
| 25 | + return ret; |
| 26 | + }; |
| 27 | + })(); |
23 | 28 |
|
24 | 29 | // if preload isn't supported, get an asynchronous load by using a non-matching media attribute |
25 | 30 | // then change that media back to its intended value on load |
26 | | - rp.bindMediaToggle = function( link, media ){ |
| 31 | + rp.bindMediaToggle = function( link ){ |
| 32 | + // remember existing media attr for ultimate state, or default to 'all' |
| 33 | + var finalMedia = link.media || "all"; |
| 34 | + |
27 | 35 | function enableStylesheet(){ |
28 | | - link.media = media; |
| 36 | + link.media = finalMedia; |
29 | 37 | } |
| 38 | + |
| 39 | + // bind load handlers to enable media |
30 | 40 | if( link.addEventListener ){ |
31 | 41 | link.addEventListener( "load", enableStylesheet ); |
32 | 42 | } else if( link.attachEvent ){ |
33 | 43 | link.attachEvent( "onload", enableStylesheet ); |
34 | 44 | } |
| 45 | + |
| 46 | + // Set rel and non-applicable media type to start an async request |
| 47 | + // note: timeout allows this to happen async to let rendering continue in IE |
| 48 | + setTimeout(function(){ |
| 49 | + link.rel = "stylesheet"; |
| 50 | + link.media = "only x"; |
| 51 | + }); |
35 | 52 | // also enable media after 3 seconds, |
36 | 53 | // which will catch very old browsers (android 2.x, old firefox) that don't support onload on link |
37 | 54 | setTimeout( enableStylesheet, 3000 ); |
38 | 55 | }; |
39 | 56 |
|
40 | 57 | // loop through link elements in DOM |
41 | 58 | rp.poly = function(){ |
| 59 | + // double check this to prevent external calls from running |
42 | 60 | if( rp.support() ){ |
43 | 61 | return; |
44 | 62 | } |
|
47 | 65 | var link = links[ i ]; |
48 | 66 | // qualify links to those with rel=preload and as=style attrs |
49 | 67 | if( link.rel === "preload" && link.getAttribute( "as" ) === "style" && !link.getAttribute( "data-loadcss" ) ){ |
50 | | - // remember existing media attr for ultimate state, or default to 'all' |
51 | | - var finalMedia = link.media || "all"; |
52 | | - // bind listeners to toggle media back |
53 | | - rp.bindMediaToggle( link, finalMedia ); |
54 | | - // if preload is not supported, kick off an asynchronous request by using a non-matching media query and rel=stylesheet |
55 | | - link.media = "x"; |
56 | | - link.rel = "stylesheet"; |
57 | | - |
58 | 68 | // prevent rerunning on link |
59 | 69 | link.setAttribute( "data-loadcss", true ); |
| 70 | + // bind listeners to toggle media back |
| 71 | + rp.bindMediaToggle( link ); |
60 | 72 | } |
61 | 73 | } |
| 74 | + }; |
| 75 | + |
| 76 | + // if unsupported, run the polyfill |
| 77 | + if( !rp.support() ){ |
| 78 | + // run once at least |
| 79 | + rp.poly(); |
| 80 | + |
62 | 81 | // rerun poly on an interval until onload |
63 | | - var run = w.setInterval( rp.poly, 300 ); |
| 82 | + var run = w.setInterval( rp.poly, 500 ); |
64 | 83 | if( w.addEventListener ){ |
65 | 84 | w.addEventListener( "load", function(){ |
66 | 85 | rp.poly(); |
|
72 | 91 | w.clearInterval( run ); |
73 | 92 | } ); |
74 | 93 | } |
75 | | - }; |
76 | | - // run once at least |
77 | | - rp.poly(); |
| 94 | + } |
| 95 | + |
| 96 | + |
78 | 97 | // commonjs |
79 | 98 | if( typeof exports !== "undefined" ){ |
80 | 99 | exports.loadCSS = loadCSS; |
|
0 commit comments