Skip to content

Instantly share code, notes, and snippets.

@coreybruyere
Last active June 3, 2016 19:41
Show Gist options
  • Save coreybruyere/1a0fd079bc70055e8a3e to your computer and use it in GitHub Desktop.
Save coreybruyere/1a0fd079bc70055e8a3e to your computer and use it in GitHub Desktop.
A copy of Chris Coyier's example https://github.com/chriscoyier/inline-svg-with-grunticon-fallback/blob/master/index.html but with a DOMContentLoaded listener so SVG's don't append before document.body is created.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Inline SVG with Grunticon Fallback</title>
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="style.css">
<script>
// Test from Modernizr
var supportsSvg = function() {
var div = document.createElement('div');
div.innerHTML = '<svg/>';
return (div.firstChild && div.firstChild.namespaceURI) == 'http://www.w3.org/2000/svg';
};
if (!supportsSvg()) {
// Could do this and use the class name, but not needed here.
// document.documentElement.className += " no-svg";
// This is the Grunticon test and CSS loader.
// It duplicates the SVG test, but that's probably OK because it also tests for Data URI support and loads that stylesheet too.
(function(e){function t(t,n,r,o){"use strict";function a(){for(var e,n=0;u.length>n;n++)u[n].href&&u[n].href.indexOf(t)>-1&&(e=!0);e?i.media=r||"all":setTimeout(a)}var i=e.document.createElement("link"),l=n||e.document.getElementsByTagName("script")[0],u=e.document.styleSheets;return i.rel="stylesheet",i.href=t,i.media="only x",i.onload=o||null,l.parentNode.insertBefore(i,l),a(),i}var n=function(r,o){"use strict";if(r&&3===r.length){var a=e.navigator,i=e.Image,l=!(!document.createElementNS||!document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect||!document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image","1.1")||e.opera&&-1===a.userAgent.indexOf("Chrome")||-1!==a.userAgent.indexOf("Series40")),u=new i;u.onerror=function(){n.method="png",n.href=r[2],t(r[2])},u.onload=function(){var e=1===u.width&&1===u.height,a=r[e&&l?0:e?1:2];n.method=e&&l?"svg":e?"datapng":"png",n.href=a,t(a,null,null,o)},u.src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==",document.documentElement.className+=" grunticon"}};n.loadCSS=t,e.grunticon=n})(this);(function(e,t){"use strict";var n=t.document,r="grunticon:",o=function(e){if(n.attachEvent?"complete"===n.readyState:"loading"!==n.readyState)e();else{var t=!1;n.addEventListener("readystatechange",function(){t||(t=!0,e())},!1)}},a=function(e){return t.document.querySelector('link[href$="'+e+'"]')},c=function(e){var t,n,o,a,c,i,u={};if(t=e.sheet,!t)return u;n=t.cssRules?t.cssRules:t.rules;for(var l=0;n.length>l;l++)o=n[l].cssText,a=r+n[l].selectorText,c=o.split(");")[0].match(/US\-ASCII\,([^"']+)/),c&&c[1]&&(i=decodeURIComponent(c[1]),u[a]=i);return u},i=function(e){var t,o,a;o="data-grunticon-embed";for(var c in e)if(a=c.slice(r.length),t=n.querySelectorAll(a+"["+o+"]"),t.length)for(var i=0;t.length>i;i++)t[i].innerHTML=e[c],t[i].style.backgroundImage="none",t[i].removeAttribute(o);return t},u=function(t){"svg"===e.method&&o(function(){i(c(a(e.href))),"function"==typeof t&&t()})};e.embedIcons=i,e.getCSS=a,e.getIcons=c,e.ready=o,e.svgLoadedCallback=u,e.embedSVG=u})(grunticon,this);
// Note the empty first item in the array. Don't do anything if supported.
grunticon(["", "/fallbacks/icons.data.png.css", "/fallbacks/icons.fallback.css"]);
} else {
// Inline SVG is supported so Ajax for the sprite.
var ajax = new XMLHttpRequest();
ajax.open("GET", "svgdefs.svg", true);
ajax.send();
ajax.onload = function(e) {
var div = document.createElement("div");
div.innerHTML = ajax.responseText;
var insertIT = function() {
document.body.insertBefore(div, document.body.childNodes[0]);
},
// Wait til all HTML and scripts are loaded
// http://stackoverflow.com/questions/27833117/typeerror-document-body-is-null
// http://stackoverflow.com/questions/8835413/difference-between-load-vs-domcontentloaded
// http://osvaldas.info/caching-svg-sprite-in-localstorage
// If document body is ready insert div
// Else wait a lil longer until DOMContentLoaded
if( document.body ) insertIT();
else document.addEventListener( 'DOMContentLoaded', insertIT );
// Old way
// document.addEventListener('DOMContentLoaded', function () {
// document.body.insertBefore(div, document.body.childNodes[0]);
// });
}
}
</script>
</head>
<body>
<div class="header">
<h1>
Inline SVG with Grunticon Fallback
</h1>
<h2>
Icons by <a href="https://icomoon.io/app">IcoMoon</a>
</h2>
</div>
<div class="icon-row">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-home"><use xlink:href="#icon-home"></use></svg><span class="mls"> icon-home</span>
</div>
<div class="icon-row">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-pencil"><use xlink:href="#icon-pencil"></use></svg><span class="mls"> icon-pencil</span>
</div>
<div class="icon-row">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-image"><use xlink:href="#icon-image"></use></svg><span class="mls"> icon-image</span>
</div>
<div class="icon-row">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-music"><use xlink:href="#icon-music"></use></svg><span class="mls"> icon-music</span>
</div>
<div class="icon-row">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-heart"><use xlink:href="#icon-heart"></use></svg><span class="mls"> icon-heart</span>
</div>
<div class="icon-row">
<button>
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-arrow-right"><use xlink:href="#icon-arrow-right"></use></svg>
icon-arrow-right
</button>
</div>
<h2>For IE 6-7</h2>
<div class="icon-row">
<div class="icon icon-credit">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-arrow-right"><use xlink:href="#icon-arrow-right"></use></svg>
</div>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment