Skip to content

Instantly share code, notes, and snippets.

@vollyimnetz
Last active October 7, 2020 13:40
Show Gist options
  • Save vollyimnetz/1df01fd0fd87af4564b545a67bec663d to your computer and use it in GitHub Desktop.
Save vollyimnetz/1df01fd0fd87af4564b545a67bec663d to your computer and use it in GitHub Desktop.
image-preload (jQuery based)
/*
@see https://gist.github.com/vollyimnetz/1df01fd0fd87af4564b545a67bec663d
HOW TO USE
data-image-preload="URL"
will add .preloadOverlay as soon as the function kicks in
will add .loaded as soon as the image is loaded
CODE
<div class="imageHolder" style="background-image:url('<?php esc_attr_e($thumb) ?>')" data-image-preload="<?php esc_attr_e($thumb) ?>">
<a class="addToLightbox" href="<?php esc_attr_e($full) ?>"></a>
</div>
PRELOAD IF IN VIEWPORT
<div class="imageHolder" data-preload-settings='{ "lazyLoadingIfInViewport":true, "timeout":50, "offset":500 }' data-image-preload="<?php esc_attr_e($thumb) ?>">
<a class="addToLightbox" href="<?php esc_attr_e($full) ?>"></a>
</div>
By Adding the attribute "data-preload-settings" you can prevent loading before the image is in viewport
The Settings for the viewport loading can be overriden with the use of an object:
data-preload-settings='{ "lazyLoadingIfInViewport":true, "timeout":50, "offset":500 }'
//add this LESS to your css
.preloadOverlay { position: relative; overflow: hidden;
&::after { position: absolute; content: ""; display: block; background: #d8d8d8; width: 100%; height: 100%; top: 0; opacity: 1;
.transition(~'opacity .6s ease, top 0s linear .6s');
}
&.loaded::after { opacity: 0; top:-100%; }
}
*/
jQuery(function($) {
doImagePreload($);
});
function doImagePreload(jQueryLib) {
var that = this;
var $ = jQueryLib;
if (!$) { $ = jQuery; }
that.loadImageByElement = function(elem) {
$('<img/>').attr('src', elem.attr('data-image-preload')).on('load', function () {
//add image as background-image to the element
elem.css({'background-image' : 'url('+elem.attr('data-image-preload')+')'});
$(this).remove(); // prevent memory leaks
elem.addClass('loaded');
});
};
/**
* Check if the jquery-elem is in viewport
* @param {jquery-elem} elem
* @returns boolean
*/
that.elemIsInViewport = function(elem,offset) {
if(elem.hasClass('loaded')) return false;
if(offset === undefined) offset = 0;
var elementTop = elem.offset().top;
var elementBottom = elementTop + elem.outerHeight();
var viewportTop = $(window).scrollTop();
var viewportBottom = viewportTop + $(window).height();
//handle offset
viewportBottom+= offset;
viewportTop-= offset;
if(viewportTop<0) viewportTop = 0;
return elementBottom > viewportTop && elementTop < viewportBottom;
};
$('*[data-image-preload]').each(function () {
var elem = $(this);
var preloadSettings = {
lazyLoadingIfInViewport:false,
timeout : 100,//lazy loading timeout for initial check --> to make sure initial scripts i.e. masonry is successfull applied
offset : 200,//lazy loading viewport offset
};
if (!elem.hasClass('loaded')) {
elem.addClass('preloadOverlay');
if(typeof elem.data('preload-settings') === "object") {
preloadSettings = $.extend(preloadSettings, elem.data('preload-settings'));
}
if(preloadSettings.lazyLoadingIfInViewport) {
//initial check, after .1sec (delay to make sure all is correctly loaded)
setTimeout(function() {
if(that.elemIsInViewport(elem, preloadSettings.offset)) { that.loadImageByElement(elem); }
},preloadSettings.timeout);
$(window).on('resize scroll', function() {
if(that.elemIsInViewport(elem, preloadSettings.offset)) { that.loadImageByElement(elem); }
});
} else {
//normal loading
that.loadImageByElement(elem);
}
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment