-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lazy load and cell size #1
Labels
Comments
I've modified the code to fix a couple of bugs and also added functionality to calculate the number of preloaded images based on a new "imgWidth" Flickity option, (if undefined, default=640), and taking into account the "wrapAround" and "cellAlign" options. It has been tested for all combinations of these options in the "ondemand" mode. Notes:
START OF CODE BLOCK /*!
* Flickity lazyLoad v1.0.0
* enables lazyLoad option for Flickity
* based on slick approach
*/
/*jshint browser: true, strict: true, undef: true, unused: true */
( function( window, factory ) {
/*global define: false, module: false, require: false */
'use strict';
// universal module definition
if ( typeof define == 'function' && define.amd ) {
// AMD
define( [
'flickity/js/index',
'fizzy-ui-utils/utils',
], function( Flickity, utils ) {
return factory( window, Flickity, utils );
});
}
else if ( typeof exports == 'object' ) {
// CommonJS
module.exports = factory(
window,
require('flickity'),
require('fizzy-ui-utils')
);
}
else {
// browser global
window.Flickity = factory(
window,
window.Flickity,
window.fizzyUIUtils
);
}
}( window, function factory( window, Flickity, utils ) {
'use strict';
Flickity.createMethods.push('_createLazyLoad');
Flickity.prototype._createLazyLoad = function() {
this.on( 'activate', this.activateLazyLoad );
}
Flickity.prototype.activateLazyLoad = function() {
if ( !this.options.lazyLoad ) {
return;
}
this.previousIndex = null; // Keep it to avoid bad behavior
this.lazyLoad();
this.previousIndex = this.selectedIndex;
function onSelect() {
if(this.selectedIndex==this.previousIndex)
return;
this.lazyLoad();
this.previousIndex = this.selectedIndex;
}
this.on('cellSelect', onSelect);
}
Flickity.prototype.lazyLoad = function() {
var _this = this;
function imageLoaded(img) {
img.removeAttribute('data-lazy');
classie.remove(img, 'flickity-loading');
var cell = _this.getParentCell( img );
_this.cellSizeChange( cell && cell.element );
}
function onImageLoaded(e) {
var img = e.target;
eventie.unbind(img, 'load', onImageLoaded);
imageLoaded(img);
}
function onImageLoadedProgressive(e) {
var img = e.target;
eventie.unbind(img, 'load', onImageLoadedProgressive);
imageLoaded(img);
_this.lazyLoad();
}
function loadImage(img, callback) {
if(img.hasAttribute('data-lazy')) {
var url = img.getAttribute('data-lazy');
eventie.bind(img, 'load', callback);
img.src = url;
}
}
function loadImages(rangeStart, rangeEnd) {
// var images = utils.filterFindElements(_this.slider.children);
var images = utils.filterFindElements(_this.slider.children, 'img'); // KCW: Modifed to select images not their div wrappers
// KCW: Modifed to remove uneccessary, (and invalid) slice operation
for (var i=rangeStart; i <= rangeEnd; i++)
{
var img = images[i];
loadImage(img, onImageLoaded);
}
}
// ==========================================
// INITIALIZATION
// ==========================================
// Apply loading class on images that don't have src attribute but data-lazy
var images = utils.filterFindElements(_this.slider.children, 'img[data-lazy]');
for( var i=0, len = images.length; i < len; i++ ) {
var img = images[i];
if(!img.hasAttribute('src')) {
classie.add(img, 'flickity-loading');
}
}
// ==========================================
// LAZY LOAD ON DEMAND
// ==========================================
// KCW: Modifed to calculate number of preloaded images based on a new "imgWidth" option and the "cellAlign" option, (currently requires jQuery)
if(_this.options.lazyLoad == 'ondemand') {
if (this.cells.length == 0 || jQuery(this.element).width() == 0) {return;}
var imgWidth = (this.options.imgWidth ? this.options.imgWidth : 640); // Default Image Width = 640px
var cellWidth = imgWidth + jQuery(this.cells[0].element).children('img').outerWidth(true);
var wrapNum = Math.ceil(jQuery(this.element).width() / cellWidth) + 1; // Add 1 in case there's room for two halves in a centered view
var rangeStart = _this.selectedIndex, rangeEnd;
switch (this.options.cellAlign)
{
case 'right':
rangeEnd = rangeStart;
rangeStart = rangeStart - wrapNum;
if (rangeStart < 0) {rangeStart = 0;}
break;
case 'center':
rangeEnd = rangeStart + Math.ceil(wrapNum/2)
rangeStart = rangeStart - Math.ceil(wrapNum/2);
if (rangeStart < 0) {rangeStart = 0;}
if (rangeEnd >= this.cells.length) {rangeEnd = this.cells.length-1;}
break;
default: // 'left'
rangeEnd = rangeStart + wrapNum;
if (rangeEnd >= this.cells.length) {rangeEnd = this.cells.length-1;}
break;
}
loadImages(rangeStart, rangeEnd); // load next imgs
if(_this.options.wrapAround === true) // Preload wrapped images if "wrapAround" option is true
{
// Using "naive" approach here, (essentially applying the "right" and "left" cases consecutively for the "center" alignment)... Could be optimised
rangeStart = _this.selectedIndex;
if (this.options.cellAlign == 'right' || this.options.cellAlign == 'center')
{
rangeEnd = rangeStart + ((this.options.cellAlign == 'center') ? Math.ceil(wrapNum/2) : 0);
rangeStart = rangeStart - ((this.options.cellAlign == 'center') ? Math.ceil(wrapNum/2) : wrapNum);
if (rangeStart < 0)
{
rangeStart = this.cells.length - ((this.options.cellAlign == 'center') ? Math.ceil(wrapNum/2) : wrapNum) - 1;
rangeEnd = this.cells.length - 1;
loadImages(rangeStart, rangeEnd);
}
}
rangeStart = _this.selectedIndex;
if (this.options.cellAlign == 'left' || this.options.cellAlign == 'center')
{
rangeEnd = rangeStart + ((this.options.cellAlign == 'center') ? Math.ceil(wrapNum/2) : wrapNum);
rangeStart = rangeStart - ((this.options.cellAlign == 'center') ? Math.ceil(wrapNum/2) : 0);
if (rangeEnd >= this.cells.length)
{
rangeStart = 0;
rangeEnd = rangeEnd - this.cells.length;
loadImages(rangeStart, rangeEnd);
}
}
}
else // Preload additional images if number is less than container element width
{
rangeStart = _this.selectedIndex;
if (this.options.cellAlign == 'right' || this.options.cellAlign == 'center')
{
rangeEnd = rangeStart + ((this.options.cellAlign == 'center') ? Math.ceil(wrapNum/2) : 0);
rangeStart = rangeStart - ((this.options.cellAlign == 'center') ? Math.ceil(wrapNum/2) : wrapNum);
if (rangeStart < 0)
{
rangeEnd = rangeEnd - rangeStart;
rangeStart = 0;
if (rangeEnd >= this.cells.length) {rangeEnd = this.cells.length-1;}
loadImages(rangeStart, rangeEnd);
}
}
rangeStart = _this.selectedIndex;
if (this.options.cellAlign == 'left' || this.options.cellAlign == 'center')
{
rangeEnd = rangeStart + ((this.options.cellAlign == 'center') ? Math.ceil(wrapNum/2) : wrapNum);
rangeStart = rangeStart - ((this.options.cellAlign == 'center') ? Math.ceil(wrapNum/2) : 0);
if (rangeEnd >= this.cells.length)
{
rangeStart = rangeStart - (rangeEnd - this.cells.length);
if (rangeStart < 0) {rangeStart = 0;}
rangeEnd = this.cells.length -1;
loadImages(rangeStart, rangeEnd);
}
}
}
}
// ==========================================
// PROGRESSIVE WAY
// ==========================================
else if(_this.options.lazyLoad == 'progressive') {
var images = utils.filterFindElements(_this.slider.children, 'img[data-lazy]');
if(images.length > 0) {
var img = images[0]; // get first child
loadImage(img, onImageLoadedProgressive);
}
}
};
return Flickity;
})); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Cells overlap and some layout problems occurs before images are loaded.
As the images are not loaded at the beginning but on a progressive way or on-demand, the slide is not able to position cells properly.
How to correctly set the size of cells before image load ?
Possible answers :
<img>
tag itself to get it before loading.cellWidth
The text was updated successfully, but these errors were encountered: