Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Handling Images in JavaScript
function imageHandler(action, image, callback) {
switch (action) {
case 'fallback':
if (image.hasAttribute('data-fallback')) {
image.style.backgroundColor = image.getAttribute('data-fallback');
}
break;
case 'parse':
var attrs = new Object();
var newImage = new Image();
// build attributes object
for (var i = 0, nodes = image.attributes; i < nodes.length; i++) {
attrs[nodes[i].nodeName] = nodes[i].nodeValue;
}
// check dpi and define new src for lazy-loading
if ('data-src' in attrs) {
attrs.src = attrs['data-src'];
}
// check dpi and define new src
var path = attrs.src.substring(0, attrs.src.lastIndexOf('.'));
var extension = attrs.src.split('.').pop();
if (window.devicePixelRatio > 2 && 'data-plus' in attrs) {
newImage.src = path + '@3x.' + extension;
} else if (window.devicePixelRatio > 1 && 'data-retina' in attrs) {
newImage.src = path + '@2x.' + extension;
} else {
newImage.src = attrs.src;
}
// garbage collection
var garbage = ['src', 'data-src', 'data-retina', 'data-plus', 'data-fallback', 'style'];
for (var i = 0; i < garbage.length; i++) {
delete attrs[garbage[i]];
}
// reattach preserved attributes
for (var attr in attrs) {
newImage.setAttribute(attr, attrs[attr]);
}
newImage.onload = function() {
image.parentNode.insertBefore(newImage, image);
image.parentNode.removeChild(image);
if (callback) {
callback();
}
};
break;
}
};
function forEach(array, callback, scope) {
for (var i = 0; i < array.length; i++) {
callback.call(scope, i, array[i]);
}
};
document.addEventListener('DOMContentLoaded', function() {
forEach(document.querySelectorAll('img[data-fallback]'), function(index, image) {
imageHandler('fallback', image);
});
}, false);
window.addEventListener('load', function() {
forEach(document.querySelectorAll('img'), function(index, image) {
imageHandler('parse', image);
});
}, false);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment