Skip to content

Instantly share code, notes, and snippets.

@pete-otaqui
Created October 18, 2012 14:42
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pete-otaqui/3912307 to your computer and use it in GitHub Desktop.
Save pete-otaqui/3912307 to your computer and use it in GitHub Desktop.
Load External Domain CSS, and get a Callback in IE7, IE8, IE9, FF, Chrome & Safari
function cssLoad(url, callback) {
var promise,
resolutions = [],
rejections = [],
resolved = false,
rejected = false,
count, id;
this.count = (this.count) ? ++this.count : 1;
count = this.count;
id = 'load-css-'+count;
promise = {
done: function(callback) {
resolutions.push(callback);
if ( resolved ) callback();
return promise;
},
fail: function(callback) {
rejections.push(callback);
if ( rejected ) callback();
return promise;
}
};
function resolve() {
resolved = true;
for ( var i=0, len=resolutions.length; i<len; i++ ) resolutions[i]();
}
function reject() {
rejected = true;
for ( var i=0, len=rejections.length; i<len; i++ ) rejections[i]();
}
var link = document.createElement('link');
link.setAttribute('id', id);
link.setAttribute('rel', 'stylesheet');
link.setAttribute('type', 'text/css');
if ( typeof link.addEventListener !== 'undefined' ) {
link.addEventListener('load', resolve, false);
link.addEventListener('error', reject, false);
} else if ( typeof link.attachEvent !== 'undefined' ) {
link.attachEvent('onload', function() {
// IE 8 gives us onload for both success and failure
// and also readyState is always "completed", even
// for failure. The only way to see if a stylesheet
// load failed from an external domain is to try and
// access its cssText, and then catch the error
// ... sweet :/
var txt, cur, i = document.styleSheets.length;
try {
while ( i-- ) {
cur = document.styleSheets[i];
if ( cur.id === id ) {
txt = cur.cssText;
resolve();
return;
}
}
} catch(e) {}
if ( !resolved ) {
reject();
}
});
}
document.getElementsByTagName('head')[0].appendChild(link);
link.setAttribute('href', url);
return promise;
}
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>CSS Load Test</title>
<script src="css-load.js"></script>
<script>
function startTests() {
startExternalTest();
startFailureTest();
}
function startExternalTest() {
setStatus('external', 'load started');
cssLoad('http://dev.otaqui.com/test.css')
.done(loadCompletedExternal)
.fail(loadFailedExternal);
}
function loadCompletedExternal() {
setStatus('external', 'load completed - TEST PASSED!');
}
function loadFailedExternal() {
setStatus('external', 'load failed - TEST FAILED!');
}
function startFailureTest() {
setStatus('failure', 'load started');
cssLoad('http://dev.otaqui.com/i_dont_exist.css')
.done(loadCompleteFailureWrongly)
.fail(loadCompleteFailure);
}
function loadCompleteFailureWrongly() {
setStatus('failure', 'load succeeded, TEST FAILED!');
}
function loadCompleteFailure() {
setStatus('failure', 'load failed - TEST PASSED!');
}
function setStatus(test, status) {
document.getElementById(test + '-status').innerHTML = status;
}
</script>
</head>
<body>
<h1>CSS Load Test</h1>
<h2>External Domain</h2>
<p id="external-status">NOT STARTED</p>
<p id="target">When I change colour, the load was successful</p>
<h2>Failure Test</h2>
<p id="failure-status">NOT STARTED</p>
<script>
function onWindowLoaded() {
setTimeout(function() {
startTests();
}, 1000);
}
if ( typeof window.addEventListener !== 'undefined' ) {
window.addEventListener('load', onWindowLoaded, false);
} else if ( typeof window.attachEvent !== 'undefined' ) {
window.attachEvent('onload', onWindowLoaded);
}
</script>
</body>
</html>
@addyosmani
Copy link

Impressive, sir. Really like that you were able to get this working properly in IE7, IE8, IE9 too :)

@dlaliberte
Copy link

Does this work on IE10 and IE11? Any browsers it doesn't work on? Thanks!

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