Skip to content

Instantly share code, notes, and snippets.

@listenrightmeow
Last active August 29, 2015 14:25
Show Gist options
  • Save listenrightmeow/7e846ad364bf8e907ae3 to your computer and use it in GitHub Desktop.
Save listenrightmeow/7e846ad364bf8e907ae3 to your computer and use it in GitHub Desktop.
Fidel Examples
window.Lodr = fidel.define('lodr', {
defaults : {
backgroundString : 'url(\'__\')',
callback : [],
height : window.innerHeight || document.documentElement.clientHeight,
srcsetTimeout : 60,
retina : !!window.hasOwnProperty('devicePixelRatio') && window.devicePixelRatio >= 2,
responsive : {
small : 480,
medium : 768,
plus : 1024,
large : 1440
},
threshold : 3.50,
timeout : 50,
webp : false,
width : window.innerWidth || document.documentElement.clientWidth
},
elements : {
active : '.active',
background : '[data-background]',
img : 'img[data-src]',
isRetina: '.is-retina',
retina : {
element : '[data-retina]:not([data-src])',
img : 'img[data-retina]:not([data-src])',
srcset : 'picture[data-retina]'
},
responsive : '[data-responsive]',
srcset : 'source[data-srcset]',
title : '.title',
video : 'video[data-load]'
},
init : function() {
var self = this,
responsive = $(this.elements.responsive),
img = [$(this.elements.img), 'lazyLoad'],
background = [$(this.elements.background), 'lazyLoadBackground'],
video = [$(this.elements.video), 'lazyLoadVideo'],
srcset = [$(this.elements.srcset), 'lazyLoadSrcset'];
this.defaults.threshold = this.defaults.height + (this.defaults.height * this.defaults.threshold);
!!window.HTMLCanvasElement && this.webpSupport();
!!this.defaults.retina && this.loadRetina();
!!responsive.length && this.loadResponsive(responsive);
$.map([img, background, video, srcset], function(node) {
if (!node[0].length) return false;
self.defaults.callback.push(node[1]);
self[node[1]]();
});
// TODO : this limits our use of the scroll event listener on window,
// find another method to attach the listener to the viewport
$(window).off('scroll').on('scroll', this.debounce());
},
buildURI : function(ctx) {
var data = ctx.data(),
format = data.hasOwnProperty('responsive') ? this.responsiveImage() : '',
webp = data.hasOwnProperty('webp'),
retina = data.hasOwnProperty('retina') && !!this.defaults.retina ? format + '-retina@2x' : format,
path = data.background.replace(/(\W\w{3,4})$/, retina + '$1'),
uri = (!!this.defaults.webp && webp) ? path.replace(/(\w{3,4})$/, 'webp') : path,
version = !!data.hasOwnProperty('bust') ? '?v=' + tradesyApp.version : '';
!!format && ctx[0].removeAttribute('data-responsive');
!!retina && ctx[0].removeAttribute('data-retina');
!!webp && ctx[0].removeAttribute('data-webp');
return uri + version;
},
debounce : function(callback) {
var func = callback,
self = this,
timer;
return function delayed() {
!!timer && clearTimeout(timer);
timer = setTimeout(function(){
for (var i = self.defaults.callback.length - 1; i >= 0; i--) {
self[self.defaults.callback[i]].apply(self);
};
clearTimeout(timer);
}, self.defaults.timeout);
}
},
forceLoad : function(images) {
images.each(function() {
$(this).attr('src', $(this).data('src'));
$(this)[0].removeAttribute('data-src');
});
},
lazyLoad : function() {
var self = this,
images = $(this.elements.img);
if (!images.length && !this.defaults.persistent) {
this.defaults.callback.splice(this.defaults.callback.indexOf('lazyLoad'), 1);
if (!$(this.elements.background + ',' + this.elements.srcset + ',' + this.elements.video).length) {
return $(window).off('scroll');
}
}
images.each(function() {
var data, retina, url, version,
img = $(this).data('src');
if (!self.visible($(this)) || !img) return;
data = $(this).data();
retina = !!data.hasOwnProperty('retina') && !!self.defaults.retina ? '-retina@2x' : '',
url = (!!retina && self.defaults.retina) ? img.replace(/(\.[\w]+)$/, '-retina@2x$1') : img;
version = !!data.hasOwnProperty('bust') ? '?v=' + tradesyApp.version : '';
$(this).attr('src', url + version);
$(this)[0].removeAttribute('data-src');
$(this).siblings(self.elements.title).css('visibility','visible');
!!retina && $(this)[0].removeAttribute('data-retina');
});
},
lazyLoadBackground : function() {
var self = this,
images = $(this.elements.background);
if (!images.length && !this.defaults.persistent) {
this.defaults.callback.splice(this.defaults.callback.indexOf('lazyLoadBackground'), 1);
if (!$(this.elements.img + ',' + this.elements.srcset + ',' + this.elements.video).length && !images.length) {
return $(window).off('scroll');
}
}
images.each(function() {
if (!self.visible($(this))) return;
var uri = self.buildURI($(this));
$(this).css('background-image', self.defaults.backgroundString.replace('__', uri));
$(this)[0].removeAttribute('data-background');
});
},
lazyLoadSrcset : function() {
var self = this,
images = $(this.elements.srcset);
if (!images.length && !this.defaults.persistent) {
this.defaults.callback.splice(this.defaults.callback.indexOf('lazyLoadSrcset'), 1);
if (!$(this.elements.background + ',' + this.elements.srcset + ',' + this.elements.video).length) {
return $(window).off('scroll');
}
}
images.each(function() {
var retina, url,
data = $(this).data(),
path = data.srcset,
picture = $(this).parents('picture'),
throttle = /small\W(jpe?g)$/.test(path);
if (!self.visible(picture)) return;
retina = !!self.defaults.retina ? '-retina@2x' : '',
url = !!retina ? path.replace(/(\.[\w]+)$/, '-retina@2x$1') : path;
version = !!data.hasOwnProperty('bust') ? '?v=' + tradesyApp.version : '';
$(this).attr('srcset', url + version);
$(this)[0].removeAttribute('data-srcset');
(!!window.picturefill && !!throttle) && self.redrawSrcset();
});
},
lazyLoadVideo : function() {
var self = this,
video = $(this.elements.video);
if ((!!tradesyApp.isMobile || !video.length) && !this.defaults.persistent) {
this.defaults.callback.splice(this.defaults.callback.indexOf('lazyLoadVideo'), 1);
if (!$(this.elements.img + ',' + this.elements.background + ',' + this.elements.srcset).length) {
return $(window).off('scroll');
}
return false;
}
video.each(function() {
var poster;
if (!self.visible($(this))) return;
poster = $(this).siblings('img');
!!poster.length && poster.remove();
$(this)[0].play();
$(this)[0].removeAttribute('data-load');
});
},
loadResponsive : function(ctx) {
var self = this;
ctx.each(function() {
if (!!$(this).attr('data-background')) return;
var url,
data = $(this).data(),
background = $(this).css('background-image').replace('url(','').replace(')','');
data.background = background;
$(this).css('background-image', 'url(' + self.buildURI($(this)) + ')');
});
},
loadRetina : function() {
var elements = $(this.elements.retina.element),
images = $(this.elements.retina.img),
srcset = $(this.elements.retina.srcset);
$('html').addClass(this.elements.isRetina.substr(1));
if (!!elements.length) {
elements.each(function() {
if ($(this).css('background-image') === 'none') return;
var uri = $(this).css('background-image').replace(/\W(jpe?g|png)/, '-retina@2x.$1'),
version = !!$(this).data().hasOwnProperty('bust') ? '?v=' + tradesyApp.version : '';
$(this).css('background-image', uri + version);
$(this)[0].removeAttribute('data-retina');
});
}
if (!!images.length) {
images.each(function() {
var uri = $(this).attr('src').replace(/(\.[\w]+)$/, '-retina@2x$1'),
version = !!$(this).data().hasOwnProperty('bust') ? '?v=' + tradesyApp.version : '';
$(this).attr('src', uri + version);
$(this)[0].removeAttribute('data-retina');
});
}
if (!!srcset.length) {
srcset.each(function() {
$('source', $(this)).each(function() {
var uri = $(this).attr('srcset').replace(/(\.[\w]+)$/, '-retina@2x$1'),
version = !!$(this).data().hasOwnProperty('bust') ? '?v=' + tradesyApp.version : '';
$(this).attr('srcset', uri + version);
});
$(this)[0].removeAttribute('data-retina');
});
}
},
redrawSrcset : function() {
var resizeThrottle;
window._picturefillWorking = true;
window.clearTimeout(resizeThrottle);
resizeThrottle = window.setTimeout(function() {
picturefill({reevaluate : true});
window._picturefillWorking = false;
}, this.defaults.srcsetTimeout);
},
responsiveImage : function() {
var ctx;
for(var prop in this.defaults.responsive) {
if (this.defaults.responsive.hasOwnProperty(prop)) {
if (window.innerWidth <= this.defaults.responsive[prop]) {
ctx = '-' + prop;
break;
} else {
ctx = '-large';
}
}
}
return ctx;
},
visible : function(node, strict) {
var height = node.height(),
width = node.width(),
rect = node[0].getBoundingClientRect();
if (!!strict) return rect;
return (
rect.top - rect.top + height >= 0 &&
rect.left + width >= 0 &&
rect.bottom <= this.defaults.threshold &&
rect.right <= this.defaults.width
);
},
webpSupport : function() {
var canvas = document.createElement('canvas');
if (!window.CanvasRenderingContext2D) return false;
this.defaults.webp = canvas.toDataURL('image/webp').indexOf('data:image/webp') + 1;
}
});
var lodr = new Lodr({ el : $('body') });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment