Skip to content

Commit

Permalink
Updated lazyload: Added function refetchElements to force lazyload to…
Browse files Browse the repository at this point in the history
… handle new images (for example in async loaded content)
  • Loading branch information
TheMaaarc committed Nov 27, 2018
1 parent fe1e637 commit 1ea1997
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 86 deletions.
2 changes: 1 addition & 1 deletion core/lazyload/LazyLoad.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public function init()
LazyLoadAsset::register($this->view);

// register js and css code with keys in order to ensure the registration is done only once
$this->view->registerJs("$('.lazy-image').lazyLoad();", View::POS_READY, self::JS_ASSET_KEY);
$this->view->registerJs("$.lazyLoad();", View::POS_READY, self::JS_ASSET_KEY);

if ($this->placeholderSrc) {
$this->view->registerCss("
Expand Down
129 changes: 74 additions & 55 deletions core/lazyload/resources/lazyload.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

(function ($) {

var initialized = false;

// Default settings, can be overwritten
var settings = {
// General settings
Expand Down Expand Up @@ -39,39 +41,40 @@
*/
var fetchImages = function() {
$(settings.imageSelector).each(function (index) {
// Add the identifying class
$(this).addClass(settings.imageIdentifierPrefix + index);

// Get some useful infos
var imageWidth = parseInt($(this).attr('data-width')),
imageHeight = parseInt($(this).attr('data-height')),
aspectRatio = settings.defaultAspectRatio,
asBackground = $(this).attr('data-as-background');

// If we have an image width & height we can calculate the aspectRatio
// the aspect ration is only used for the div placeholder
if (imageWidth && imageHeight) {
aspectRatio = imageHeight / imageWidth;
}

var divPlaceholderExists = false;
if($(this).next('.' + settings.placeholderClass).length >= 1) {
divPlaceholderExists = true;
}
if(!$(this).hasClass('loaded')) {
// Add the identifying class
$(this).addClass(settings.imageIdentifierPrefix + index);

// Get some useful infos
var imageWidth = parseInt($(this).attr('data-width')),
imageHeight = parseInt($(this).attr('data-height')),
aspectRatio = settings.defaultAspectRatio,
asBackground = $(this).attr('data-as-background');

// If we have an image width & height we can calculate the aspectRatio
// the aspect ration is only used for the div placeholder
if (imageWidth && imageHeight) {
aspectRatio = imageHeight / imageWidth;
}

images.push({
id: index,
source: $(this).attr('data-src'),
boundaries: {},
hasPlaceholderImage: $(this).hasClass('lazyimage'),
divPlaceholderExists: divPlaceholderExists,
width: imageWidth,
height: imageHeight,
aspectRatio: aspectRatio,
asBackground: asBackground,
html: $(this)[0].outerHTML
});
var divPlaceholderExists = false;
if($(this).next('.' + settings.placeholderClass).length >= 1) {
divPlaceholderExists = true;
}

images.push({
id: index,
source: $(this).attr('data-src'),
boundaries: {},
hasPlaceholderImage: $(this).hasClass('lazyimage'),
divPlaceholderExists: divPlaceholderExists,
width: imageWidth,
height: imageHeight,
aspectRatio: aspectRatio,
asBackground: asBackground,
html: $(this)[0].outerHTML
});
}
});

insertPlaceholder();
Expand Down Expand Up @@ -185,7 +188,7 @@
})
} else if (!image.hasPlaceholderImage) {
// If the image has a placeholder div we need to remove it
$placeholder.remove();
$placeholder.hide();
}

// Trigger a success event
Expand Down Expand Up @@ -235,34 +238,50 @@
}
};

$.fn.lazyLoad = function (options) {
$.lazyLoad = function (options) {
if(typeof options === 'string') {
switch(options) {
case 'refetchElements':
fetchImages();
loadVisibleImages();
break;
}
} else if (!initialized) {
initialized = true;

if(options) {
settings = $.extend(settings, options);
}

// Fetch images to prepare the iamges array
fetchImages();
// Fetch images to prepare the iamges array
fetchImages();

// Regularly check for changes and run needed functions
setInterval(function () {
if (status.viewportChanged === true || status.touchScrolling === true) {
loadVisibleImages();
status.viewportChanged = false;
// Regularly check for changes and run needed functions
setInterval(function () {
if (status.viewportChanged === true || status.touchScrolling === true) {
loadVisibleImages();
status.viewportChanged = false;
status.touchScrolling = false;
}
}, 250);

// Listen to different events the script needs to react to
$(document).on('touchmove', function () {
status.touchScrolling = true;
});
$(window).on('scroll resize', function () {
status.viewportChanged = true;
status.touchScrolling = false;
}
}, 250);
});
$(window).on('resize', function () {
status.resized = true;
});

// Listen to different events the script needs to react to
$(document).on('touchmove', function () {
status.touchScrolling = true;
});
$(window).on('scroll resize', function () {
status.viewportChanged = true;
status.touchScrolling = false;
});
$(window).on('resize', function () {
status.resized = true;
});
// Finally, start loading of the first visible images (if there are any)
loadVisibleImages();
}

// Finally, start loading of the first visible images (if there are any)
loadVisibleImages();
return this;
};

}(jQuery));
2 changes: 1 addition & 1 deletion core/lazyload/resources/lazyload.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 15 additions & 29 deletions tests/js/LazyLoadTest.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,20 @@
describe("Test LazyLoading: Placeholder", function() {
var basicLazyLoadImageFixture = '<img class="lazy-image" data-src="https://source.unsplash.com/random/500x250" data-width="500" data-height="250">';

it("should exist", function () {
setFixtures(basicLazyLoadImageFixture);

// Init lazyload which should insert placeholder
$('.lazy-image').lazyLoad();

// Check for placeholder
expect($('.lazy-image').next('.lazy-placeholder')[0].outerHTML).toBe(
'<div class="lazy-placeholder lazy-image "><div style="height: 0px; padding-bottom: 50%;"></div><div class="loader"></div></div>'
);
});

});

describe("Test LazyLoading: Image loading", function() {
var originalTimeout;
var imageId;
var basicLazyLoadImageFixture = '<img class="lazy-image" data-src="https://source.unsplash.com/random/500x250" data-width="500" data-height="250">';

beforeEach(function(done) {
beforeEach(function() {
// Increase timeout to 30 seconds in case unsplash has a
// major problem
originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;
});

it("should have class `loaded`", function (done) {
var imageId;

// Set imageLoaded to false and wait for event sent by the lazyloading plugin
var imageLoaded = false;
$(document).on('lazyimage-loaded', function(e, info) {
$(document).one('lazyimage-loaded', function(e, info) {
if(info.type == 'success') {
imageId = info.imageId;
imageLoaded = true;
Expand All @@ -39,23 +25,23 @@ describe("Test LazyLoading: Image loading", function() {
setFixtures(basicLazyLoadImageFixture);

// Init lazyloading
$('.lazy-image').lazyLoad();
$.lazyLoad();

// Check every second if the image has been loaded
// Check every half second if the image has been loaded
// and if so, call the done() function
var startTime = Date.now();
setInterval(function() {
if(imageLoaded) {
// Check if this.imageId has class loaded
expect($(imageId).hasClass('loaded')).toBe(true);
done();
} else {
console.log('Waiting for image to load... (' + Math.round((Date.now() - startTime) / 1000) + 's)');
}
}, 1000);
}, 500);
});

afterEach(function() {
jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
});

it("should have class `loaded`", function () {
// Check if this.imageId has class loaded
expect($(imageId).hasClass('loaded')).toBe(true);
});
});
});

0 comments on commit 1ea1997

Please sign in to comment.