Skip to content

Instantly share code, notes, and snippets.

@aFarkas
Last active January 3, 2024 20:18
Show Gist options
  • Save aFarkas/34dde117000ec7075053 to your computer and use it in GitHub Desktop.
Save aFarkas/34dde117000ec7075053 to your computer and use it in GitHub Desktop.
link[rel="preload"] polyfill
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- we use 'preload_' instead of 'preload' to make it testable in chrome -->
<link rel="preload_" onload="console.log(this, 'script');" href="http://code.jquery.com/jquery-1.12.1.js" as="script" />
<link rel="preload_" onload="console.log(this, 'style');" href="https://cdn.jsdelivr.net/bootstrap/3.3.6/css/bootstrap.min.css" as="style" />
<link rel="preload_" onload="console.log(this, 'font');" href="LatoLatin-Regular.woff" as="font" type="font/woff" crossorigin="" />
<script src="preload-core.js"></script>
<script src="preload-as-script.js"></script>
<script src="preload-as-style.js"></script>
<script src="preload-as-font.js"></script>
<script>
preloadFill.run('preload_');
</script>
</head>
<body>
</body>
</html>
(function(){
'use strict';
var TIMEOUT = 4000;
var COMPAREFONT = 'Comic Sans MS';
var id = Date.now();
window.preloadFill.add('font', function(link, iframeDocument, iframeWindow, callback){
var spans, timer;
var fontName = 'font'+id;
var now = Date.now();
var div = iframeDocument.createElement('div');
var markup = '<span style="float:left;font-weight:400;font-style:normal;font-size:99px;">QW@HhsXJ</span>';
var cleanup = function(status){
clearInterval(timer);
callback(status);
iframeDocument.documentElement.removeChild(div);
};
markup += markup;
markup = '<style>@font-face {' +
'font-family: "'+ fontName +'";' +
'src: url("'+ link.href +'")'+ (link.type ? ' format("'+ (link.type.split('/')[1] || link.type) +'")' : '') +';' +
'font-weight: 400;' +
'font-style: normal;' +
'</style>' + markup
;
div.innerHTML = markup;
spans = div.querySelectorAll('span');
spans[0].style.fontFamily = fontName + ', '+ COMPAREFONT;
spans[1].style.fontFamily = COMPAREFONT;
iframeDocument.documentElement.appendChild(div);
timer = setInterval(function(){
if(spans[0].offsetWidth != spans[1].offsetWidth){
cleanup('load');
} else if(Date.now() - now > TIMEOUT){
cleanup('timeout');
}
}, 33);
id++;
});
})();
(function(){
'use strict';
window.preloadFill.add('script', function(link, iframeDocument, iframeWindow, callback){
var script = iframeDocument.createElement('script');
var stop = function(status){
callback(status);
iframeDocument.documentElement.removeChild(script);
};
script.src = link.href;
iframeDocument.documentElement.appendChild(script);
script.onload = function(){
stop('load');
};
script.onerror = function(){
stop('error');
};
});
})();
(function(){
'use strict';
window.preloadFill.add('style', function(link, iframeDocument, iframeWindow, callback){
var timer;
var sheets = document.styleSheets;
var preload = iframeDocument.createElement('link');
var clear = function(){
clearInterval(timer);
preload.onload = null;
preload.onerror = null;
iframeDocument.documentElement.removeChild(preload);
};
var onload = function(){
clear();
callback('load');
};
preload.href = link.href;
preload.rel = 'stylesheet';
iframeDocument.documentElement.appendChild(preload);
timer = setInterval(function(){
var resolvedHref = preload.href;
var i = sheets.length;
while( i-- ){
if( sheets[ i ].href == resolvedHref ){
onload();
break;
}
}
}, 20);
preload.onload = onload;
preload.onerror = function(){
clear();
callback('error');
};
});
})();
(function (window, document, undefined) {
'use strict';
var iframe, iframeWindow, iframeDocument;
var elemSymbol = window.Symbol ? Symbol('_preload') : '_preload' + (Date.now());
var logged = {};
var as = {};
var supportsPreload = false;
try {
supportsPreload = document.createElement('link').relList.supports('preload');
} catch(e){}
function createIframe() {
if(!iframe){
iframe = document.createElement('iframe');
iframe.setAttribute('role', 'presentation');
iframe.tabIndex = -1;
iframe.style.visibility = 'hidden';
iframe.style.position = 'absolute';
iframe.style.top = '-9999px';
iframe.src = 'javascript:false';
iframe.allowTransparency = true;
(document.body || document.documentElement).appendChild(iframe);
iframeWindow = iframe.contentWindow || iframe.contentDocument;
iframeDocument = iframeWindow.document;
iframeDocument.write();
iframeDocument.close();
}
}
var triggerEvent = function(elem, name){
var event = document.createEvent('CustomEvent');
event.initCustomEvent(name, false, false, 'polyfill');
elem.dispatchEvent(event);
return event;
};
function add(type, fn){
as[type] = fn;
}
function processPreload(link){
var data = {
as: link.getAttribute('as'),
href: link.href,
type: link.getAttribute('type'),
media: link.media,
link: link,
};
link[elemSymbol] = true;
if(as[data.as] && (!link.media || matchMedia(link.media).matches)){
createIframe();
as[data.as](data, iframeDocument, iframeWindow, function(status){
triggerEvent(link, status);
});
} else if(window.console && !logged[data.as]){
logged[data.as] = true;
console.log("don't know as: " + data.as);
}
}
function findPreloads(context, preloadAttr){
var i, len;
if(typeof context == 'string'){
preloadAttr = context;
context = null;
}
preloadAttr = preloadAttr || 'preload';
context = context || document;
if(supportsPreload && preloadAttr == 'preload'){return;}
var preloads = context.querySelectorAll('link[rel="'+ preloadAttr +'"]');
for(i = 0, len = preloads.length; i < len; i++){
if(!preloads[i][elemSymbol]){
processPreload(preloads[i]);
}
}
}
window.preloadFill = {
add: add,
run: findPreloads,
};
})(window, document);
@bsed
Copy link

bsed commented Aug 7, 2017

不错~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment