magnific-popup
Version:
Lightbox and modal dialog plugin. Can display inline HTML, iframes (YouTube video, Vimeo, Google Maps), or an image gallery. Animation effects are added with CSS3 transitions. For jQuery or Zepto.
246 lines (200 loc) • 5.62 kB
JavaScript
var _imgInterval,
_getTitle = function(item) {
if(item.data && item.data.title !== undefined)
return item.data.title;
var src = mfp.st.image.titleSrc;
if(src) {
if(typeof src === "function") {
return src.call(mfp, item);
} else if(item.el) {
return item.el.attr(src) || '';
}
}
return '';
};
$.magnificPopup.registerModule('image', {
options: {
markup: '<div class="mfp-figure">'+
'<div class="mfp-close"></div>'+
'<figure>'+
'<div class="mfp-img"></div>'+
'<figcaption>'+
'<div class="mfp-bottom-bar">'+
'<div class="mfp-title"></div>'+
'<div class="mfp-counter"></div>'+
'</div>'+
'</figcaption>'+
'</figure>'+
'</div>',
cursor: 'mfp-zoom-out-cur',
titleSrc: 'title',
verticalFit: true,
tError: 'The image could not be loaded.'
},
proto: {
initImage: function() {
var imgSt = mfp.st.image,
ns = '.image';
mfp.types.push('image');
_mfpOn(OPEN_EVENT+ns, function() {
if(mfp.currItem.type === 'image' && imgSt.cursor) {
$(document.body).addClass(imgSt.cursor);
}
});
_mfpOn(CLOSE_EVENT+ns, function() {
if(imgSt.cursor) {
$(document.body).removeClass(imgSt.cursor);
}
_window.off('resize' + EVENT_NS);
});
_mfpOn('Resize'+ns, mfp.resizeImage);
if(mfp.isLowIE) {
_mfpOn('AfterChange', mfp.resizeImage);
}
},
resizeImage: function() {
var item = mfp.currItem;
if(!item || !item.img) return;
if(mfp.st.image.verticalFit) {
var decr = 0;
// fix box-sizing in ie7/8
if(mfp.isLowIE) {
decr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10);
}
item.img.css('max-height', mfp.wH-decr);
}
},
_onImageHasSize: function(item) {
if(item.img) {
item.hasSize = true;
if(_imgInterval) {
clearInterval(_imgInterval);
}
item.isCheckingImgSize = false;
_mfpTrigger('ImageHasSize', item);
if(item.imgHidden) {
if(mfp.content)
mfp.content.removeClass('mfp-loading');
item.imgHidden = false;
}
}
},
/**
* Function that loops until the image has size to display elements that rely on it asap
*/
findImageSize: function(item) {
var counter = 0,
img = item.img[0],
mfpSetInterval = function(delay) {
if(_imgInterval) {
clearInterval(_imgInterval);
}
// decelerating interval that checks for size of an image
_imgInterval = setInterval(function() {
if(img.naturalWidth > 0) {
mfp._onImageHasSize(item);
return;
}
if(counter > 200) {
clearInterval(_imgInterval);
}
counter++;
if(counter === 3) {
mfpSetInterval(10);
} else if(counter === 40) {
mfpSetInterval(50);
} else if(counter === 100) {
mfpSetInterval(500);
}
}, delay);
};
mfpSetInterval(1);
},
getImage: function(item, template) {
var guard = 0,
imgSt = mfp.st.image,
// image error handler
onLoadError = function() {
if(item) {
item.img.off('.mfploader');
if(item === mfp.currItem){
mfp._onImageHasSize(item);
mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
}
item.hasSize = true;
item.loaded = true;
item.loadError = true;
}
},
// image load complete handler
onLoadComplete = function() {
if(item) {
if (item.img[0].complete) {
item.img.off('.mfploader');
if(item === mfp.currItem){
mfp._onImageHasSize(item);
mfp.updateStatus('ready');
}
item.hasSize = true;
item.loaded = true;
_mfpTrigger('ImageLoadComplete');
}
else {
// if image complete check fails 200 times (20 sec), we assume that there was an error.
guard++;
if(guard < 200) {
setTimeout(onLoadComplete,100);
} else {
onLoadError();
}
}
}
};
var el = template.find('.mfp-img');
if(el.length) {
var img = document.createElement('img');
img.className = 'mfp-img';
if(item.el && item.el.find('img').length) {
img.alt = item.el.find('img').attr('alt');
}
item.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError);
img.src = item.src;
// without clone() "error" event is not firing when IMG is replaced by new IMG
// TODO: find a way to avoid such cloning
if(el.is('img')) {
item.img = item.img.clone();
}
img = item.img[0];
if(img.naturalWidth > 0) {
item.hasSize = true;
} else if(!img.width) {
item.hasSize = false;
}
}
mfp._parseMarkup(template, {
title: _getTitle(item),
img_replaceWith: item.img
}, item);
mfp.resizeImage();
if(item.hasSize) {
if(_imgInterval) clearInterval(_imgInterval);
if(item.loadError) {
template.addClass('mfp-loading');
mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
} else {
template.removeClass('mfp-loading');
mfp.updateStatus('ready');
}
return template;
}
mfp.updateStatus('loading');
item.loading = true;
if(!item.hasSize) {
item.imgHidden = true;
template.addClass('mfp-loading');
mfp.findImageSize(item);
}
return template;
}
}
});