Created
January 18, 2017 05:01
-
-
Save sudipbd/3fe42f4992352107d3319fb0fe85123a to your computer and use it in GitHub Desktop.
Simple lightbox for image
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="gallery-images"> | |
<div class="col-md-6 col-sm-6 col-xs-6"> | |
<div class="gallery_single active"> | |
<a class="fancybox" rel="group" href="img/gallery1.jpg" title="Image Caption"> | |
<img src="img/gallery1.jpg" alt="gallery image" /> | |
</a> | |
</div> | |
</div> | |
<div class="col-md-2 col-sm-6 col-xs-6"> | |
<div class="gallery_single"> | |
<a class="fancybox" rel="group" href="img/gallery1.jpg" title="Image Caption"> | |
<img src="img/gallery1.jpg" alt="gallery image" /> | |
</a> | |
</div> | |
</div> | |
<div class="col-md-2 col-sm-6 col-xs-6"> | |
<div class="gallery_single"> | |
<a class="fancybox" rel="group" href="img/gallery1.jpg" title="Image Caption"> | |
<img src="img/gallery1.jpg" alt="gallery image" /> | |
</a> | |
</div> | |
</div> | |
<div class="col-md-2 col-sm-6 col-xs-6"> | |
<div class="gallery_single"> | |
<a class="fancybox" rel="group" href="img/gallery1.jpg" title="Image Caption"> | |
<img src="img/gallery1.jpg" alt="gallery image" /> | |
</a> | |
</div> | |
</div> | |
<div class="col-md-2 col-sm-6 col-xs-6"> | |
<div class="gallery_single"> | |
<a class="fancybox" rel="group" href="img/gallery1.jpg" title="Image Caption"> | |
<img src="img/gallery1.jpg" alt="gallery image" /> | |
</a> | |
</div> | |
</div> | |
<div class="col-md-2 col-sm-6 col-xs-6"> | |
<div class="gallery_single"> | |
<a class="fancybox" rel="group" href="img/gallery1.jpg" title="Image Caption"> | |
<img src="img/gallery1.jpg" alt="gallery image" /> | |
</a> | |
</div> | |
</div> | |
<div class="col-md-2 col-sm-6 col-xs-6"> | |
<div class="gallery_single"> | |
<a class="fancybox" rel="group" href="img/gallery1.jpg" title="Image Caption"> | |
<img src="img/gallery1.jpg" alt="gallery image" /> | |
</a> | |
</div> | |
</div> | |
<div class="col-md-2 col-sm-6 col-xs-6"> | |
<div class="gallery_single"> | |
<a class="fancybox" rel="group" href="img/gallery1.jpg" title="Image Caption"> | |
<img src="img/gallery1.jpg" alt="gallery image" /> | |
</a> | |
</div> | |
</div> | |
<div class="col-md-2 col-sm-6 col-xs-6"> | |
<div class="gallery_single"> | |
<a class="fancybox" rel="group" href="img/gallery1.jpg" title="Image Caption"> | |
<img src="img/gallery1.jpg" alt="gallery image" /> | |
</a> | |
</div> | |
</div> | |
<div class="col-md-2 col-sm-6 col-xs-6"> | |
<div class="gallery_single"> | |
<a class="fancybox" rel="group" href="img/gallery1.jpg" title="Image Caption"> | |
<img src="img/gallery1.jpg" alt="gallery image" /> | |
</a> | |
</div> | |
</div> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */ | |
.fancybox-wrap, | |
.fancybox-skin, | |
.fancybox-outer, | |
.fancybox-inner, | |
.fancybox-image, | |
.fancybox-wrap iframe, | |
.fancybox-wrap object, | |
.fancybox-nav, | |
.fancybox-nav span, | |
.fancybox-tmp | |
{ | |
padding: 0; | |
margin: 0; | |
border: 0; | |
outline: none; | |
vertical-align: top; | |
} | |
.fancybox-wrap { | |
position: absolute; | |
top: 0; | |
left: 0; | |
-webkit-transform: translate3d(0, 0, 0); | |
transform: translate3d(0, 0, 0); | |
z-index: 8020; | |
} | |
.fancybox-skin { | |
position: relative; | |
background: #f9f9f9; | |
color: #444; | |
text-shadow: none; | |
-webkit-border-radius: 4px; | |
-moz-border-radius: 4px; | |
border-radius: 4px; | |
} | |
.fancybox-opened { | |
z-index: 8030; | |
} | |
.fancybox-opened .fancybox-skin { | |
-webkit-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); | |
-moz-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); | |
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); | |
} | |
.fancybox-outer, .fancybox-inner { | |
position: relative; | |
} | |
.fancybox-inner { | |
overflow: hidden; | |
} | |
.fancybox-type-iframe .fancybox-inner { | |
-webkit-overflow-scrolling: touch; | |
} | |
.fancybox-error { | |
color: #444; | |
font: 14px/20px "Helvetica Neue",Helvetica,Arial,sans-serif; | |
margin: 0; | |
padding: 15px; | |
white-space: nowrap; | |
} | |
.fancybox-image, .fancybox-iframe { | |
display: block; | |
width: 100%; | |
height: 100%; | |
} | |
.fancybox-image { | |
max-width: 100%; | |
max-height: 100%; | |
} | |
#fancybox-loading, .fancybox-close, .fancybox-prev span, .fancybox-next span { | |
background-image: url(fancybox_sprite.png); | |
} | |
#fancybox-loading { | |
position: fixed; | |
top: 50%; | |
left: 50%; | |
margin-top: -22px; | |
margin-left: -22px; | |
background-position: 0 -108px; | |
opacity: 0.8; | |
cursor: pointer; | |
z-index: 8060; | |
} | |
#fancybox-loading div { | |
width: 44px; | |
height: 44px; | |
background: url(fancybox_loading.gif) center center no-repeat; | |
} | |
.fancybox-close { | |
position: absolute; | |
top: -18px; | |
right: -18px; | |
width: 36px; | |
height: 36px; | |
cursor: pointer; | |
z-index: 8040; | |
} | |
.fancybox-nav { | |
position: absolute; | |
top: 0; | |
width: 40%; | |
height: 100%; | |
cursor: pointer; | |
text-decoration: none; | |
background: transparent url(blank.gif); /* helps IE */ | |
-webkit-tap-highlight-color: rgba(0,0,0,0); | |
z-index: 8040; | |
} | |
.fancybox-prev { | |
left: 0; | |
} | |
.fancybox-next { | |
right: 0; | |
} | |
.fancybox-nav span { | |
position: absolute; | |
top: 50%; | |
width: 36px; | |
height: 34px; | |
margin-top: -18px; | |
cursor: pointer; | |
z-index: 8040; | |
visibility: hidden; | |
} | |
.fancybox-prev span { | |
left: 10px; | |
background-position: 0 -36px; | |
} | |
.fancybox-next span { | |
right: 10px; | |
background-position: 0 -72px; | |
} | |
.fancybox-nav:hover span { | |
visibility: visible; | |
} | |
.fancybox-tmp { | |
position: absolute; | |
top: -99999px; | |
left: -99999px; | |
max-width: 99999px; | |
max-height: 99999px; | |
overflow: visible !important; | |
} | |
/* Overlay helper */ | |
.fancybox-lock { | |
overflow: visible !important; | |
width: auto; | |
} | |
.fancybox-lock body { | |
overflow: hidden !important; | |
} | |
.fancybox-lock-test { | |
overflow-y: hidden !important; | |
} | |
.fancybox-overlay { | |
position: absolute; | |
top: 0; | |
left: 0; | |
overflow: hidden; | |
display: none; | |
z-index: 8010; | |
background: url(fancybox_overlay.png); | |
} | |
.fancybox-overlay-fixed { | |
position: fixed; | |
bottom: 0; | |
right: 0; | |
} | |
.fancybox-lock .fancybox-overlay { | |
overflow: auto; | |
overflow-y: scroll; | |
} | |
/* Title helper */ | |
.fancybox-title { | |
visibility: hidden; | |
font: normal 13px/20px "Helvetica Neue",Helvetica,Arial,sans-serif; | |
position: relative; | |
text-shadow: none; | |
z-index: 8050; | |
} | |
.fancybox-opened .fancybox-title { | |
visibility: visible; | |
} | |
.fancybox-title-float-wrap { | |
position: absolute; | |
bottom: 0; | |
right: 50%; | |
margin-bottom: -35px; | |
z-index: 8050; | |
text-align: center; | |
} | |
.fancybox-title-float-wrap .child { | |
display: inline-block; | |
margin-right: -100%; | |
padding: 2px 20px; | |
background: transparent; /* Fallback for web browsers that doesn't support RGBa */ | |
background: rgba(0, 0, 0, 0.8); | |
-webkit-border-radius: 15px; | |
-moz-border-radius: 15px; | |
border-radius: 15px; | |
text-shadow: 0 1px 2px #222; | |
color: #FFF; | |
font-weight: bold; | |
line-height: 24px; | |
white-space: nowrap; | |
} | |
.fancybox-title-outside-wrap { | |
position: relative; | |
margin-top: 10px; | |
color: #fff; | |
} | |
.fancybox-title-inside-wrap { | |
padding-top: 10px; | |
} | |
.fancybox-title-over-wrap { | |
position: absolute; | |
bottom: 0; | |
left: 0; | |
color: #fff; | |
padding: 10px; | |
background: #000; | |
background: rgba(0, 0, 0, .8); | |
} | |
/*Retina graphics!*/ | |
@media only screen and (-webkit-min-device-pixel-ratio: 1.5), | |
only screen and (min--moz-device-pixel-ratio: 1.5), | |
only screen and (min-device-pixel-ratio: 1.5){ | |
#fancybox-loading, .fancybox-close, .fancybox-prev span, .fancybox-next span { | |
background-image: url([email protected]); | |
background-size: 44px 152px; /*The size of the normal image, half the size of the hi-res image*/ | |
} | |
#fancybox-loading div { | |
background-image: url([email protected]); | |
background-size: 24px 24px; /*The size of the normal image, half the size of the hi-res image*/ | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* fancyBox - jQuery Plugin | |
* version: 2.1.5 (Fri, 14 Jun 2013) | |
* requires jQuery v1.6 or later | |
* | |
* Examples at http://fancyapps.com/fancybox/ | |
* License: www.fancyapps.com/fancybox/#license | |
* | |
* Copyright 2012 Janis Skarnelis - [email protected] | |
* | |
*/ | |
;(function (window, document, $, undefined) { | |
"use strict"; | |
var H = $("html"), | |
W = $(window), | |
D = $(document), | |
F = $.fancybox = function () { | |
F.open.apply( this, arguments ); | |
}, | |
IE = navigator.userAgent.match(/msie/i), | |
didUpdate = null, | |
isTouch = document.createTouch !== undefined, | |
isQuery = function(obj) { | |
return obj && obj.hasOwnProperty && obj instanceof $; | |
}, | |
isString = function(str) { | |
return str && $.type(str) === "string"; | |
}, | |
isPercentage = function(str) { | |
return isString(str) && str.indexOf('%') > 0; | |
}, | |
isScrollable = function(el) { | |
return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight))); | |
}, | |
getScalar = function(orig, dim) { | |
var value = parseInt(orig, 10) || 0; | |
if (dim && isPercentage(orig)) { | |
value = F.getViewport()[ dim ] / 100 * value; | |
} | |
return Math.ceil(value); | |
}, | |
getValue = function(value, dim) { | |
return getScalar(value, dim) + 'px'; | |
}; | |
$.extend(F, { | |
// The current version of fancyBox | |
version: '2.1.5', | |
defaults: { | |
padding : 15, | |
margin : 20, | |
width : 800, | |
height : 600, | |
minWidth : 100, | |
minHeight : 100, | |
maxWidth : 9999, | |
maxHeight : 9999, | |
pixelRatio: 1, // Set to 2 for retina display support | |
autoSize : true, | |
autoHeight : false, | |
autoWidth : false, | |
autoResize : true, | |
autoCenter : !isTouch, | |
fitToView : true, | |
aspectRatio : false, | |
topRatio : 0.5, | |
leftRatio : 0.5, | |
scrolling : 'auto', // 'auto', 'yes' or 'no' | |
wrapCSS : '', | |
arrows : true, | |
closeBtn : true, | |
closeClick : false, | |
nextClick : false, | |
mouseWheel : true, | |
autoPlay : false, | |
playSpeed : 3000, | |
preload : 3, | |
modal : false, | |
loop : true, | |
ajax : { | |
dataType : 'html', | |
headers : { 'X-fancyBox': true } | |
}, | |
iframe : { | |
scrolling : 'auto', | |
preload : true | |
}, | |
swf : { | |
wmode: 'transparent', | |
allowfullscreen : 'true', | |
allowscriptaccess : 'always' | |
}, | |
keys : { | |
next : { | |
13 : 'left', // enter | |
34 : 'up', // page down | |
39 : 'left', // right arrow | |
40 : 'up' // down arrow | |
}, | |
prev : { | |
8 : 'right', // backspace | |
33 : 'down', // page up | |
37 : 'right', // left arrow | |
38 : 'down' // up arrow | |
}, | |
close : [27], // escape key | |
play : [32], // space - start/stop slideshow | |
toggle : [70] // letter "f" - toggle fullscreen | |
}, | |
direction : { | |
next : 'left', | |
prev : 'right' | |
}, | |
scrollOutside : true, | |
// Override some properties | |
index : 0, | |
type : null, | |
href : null, | |
content : null, | |
title : null, | |
// HTML templates | |
tpl: { | |
wrap : '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>', | |
image : '<img class="fancybox-image" src="{href}" alt="" />', | |
iframe : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + (IE ? ' allowtransparency="true"' : '') + '></iframe>', | |
error : '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>', | |
closeBtn : '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>', | |
next : '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>', | |
prev : '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>', | |
loading : '<div id="fancybox-loading"><div></div></div>' | |
}, | |
// Properties for each animation type | |
// Opening fancyBox | |
openEffect : 'fade', // 'elastic', 'fade' or 'none' | |
openSpeed : 250, | |
openEasing : 'swing', | |
openOpacity : true, | |
openMethod : 'zoomIn', | |
// Closing fancyBox | |
closeEffect : 'fade', // 'elastic', 'fade' or 'none' | |
closeSpeed : 250, | |
closeEasing : 'swing', | |
closeOpacity : true, | |
closeMethod : 'zoomOut', | |
// Changing next gallery item | |
nextEffect : 'elastic', // 'elastic', 'fade' or 'none' | |
nextSpeed : 250, | |
nextEasing : 'swing', | |
nextMethod : 'changeIn', | |
// Changing previous gallery item | |
prevEffect : 'elastic', // 'elastic', 'fade' or 'none' | |
prevSpeed : 250, | |
prevEasing : 'swing', | |
prevMethod : 'changeOut', | |
// Enable default helpers | |
helpers : { | |
overlay : true, | |
title : true | |
}, | |
// Callbacks | |
onCancel : $.noop, // If canceling | |
beforeLoad : $.noop, // Before loading | |
afterLoad : $.noop, // After loading | |
beforeShow : $.noop, // Before changing in current item | |
afterShow : $.noop, // After opening | |
beforeChange : $.noop, // Before changing gallery item | |
beforeClose : $.noop, // Before closing | |
afterClose : $.noop // After closing | |
}, | |
//Current state | |
group : {}, // Selected group | |
opts : {}, // Group options | |
previous : null, // Previous element | |
coming : null, // Element being loaded | |
current : null, // Currently loaded element | |
isActive : false, // Is activated | |
isOpen : false, // Is currently open | |
isOpened : false, // Have been fully opened at least once | |
wrap : null, | |
skin : null, | |
outer : null, | |
inner : null, | |
player : { | |
timer : null, | |
isActive : false | |
}, | |
// Loaders | |
ajaxLoad : null, | |
imgPreload : null, | |
// Some collections | |
transitions : {}, | |
helpers : {}, | |
/* | |
* Static methods | |
*/ | |
open: function (group, opts) { | |
if (!group) { | |
return; | |
} | |
if (!$.isPlainObject(opts)) { | |
opts = {}; | |
} | |
// Close if already active | |
if (false === F.close(true)) { | |
return; | |
} | |
// Normalize group | |
if (!$.isArray(group)) { | |
group = isQuery(group) ? $(group).get() : [group]; | |
} | |
// Recheck if the type of each element is `object` and set content type (image, ajax, etc) | |
$.each(group, function(i, element) { | |
var obj = {}, | |
href, | |
title, | |
content, | |
type, | |
rez, | |
hrefParts, | |
selector; | |
if ($.type(element) === "object") { | |
// Check if is DOM element | |
if (element.nodeType) { | |
element = $(element); | |
} | |
if (isQuery(element)) { | |
obj = { | |
href : element.data('fancybox-href') || element.attr('href'), | |
title : $('<div/>').text( element.data('fancybox-title') || element.attr('title') || '' ).html(), | |
isDom : true, | |
element : element | |
}; | |
if ($.metadata) { | |
$.extend(true, obj, element.metadata()); | |
} | |
} else { | |
obj = element; | |
} | |
} | |
href = opts.href || obj.href || (isString(element) ? element : null); | |
title = opts.title !== undefined ? opts.title : obj.title || ''; | |
content = opts.content || obj.content; | |
type = content ? 'html' : (opts.type || obj.type); | |
if (!type && obj.isDom) { | |
type = element.data('fancybox-type'); | |
if (!type) { | |
rez = element.prop('class').match(/fancybox\.(\w+)/); | |
type = rez ? rez[1] : null; | |
} | |
} | |
if (isString(href)) { | |
// Try to guess the content type | |
if (!type) { | |
if (F.isImage(href)) { | |
type = 'image'; | |
} else if (F.isSWF(href)) { | |
type = 'swf'; | |
} else if (href.charAt(0) === '#') { | |
type = 'inline'; | |
} else if (isString(element)) { | |
type = 'html'; | |
content = element; | |
} | |
} | |
// Split url into two pieces with source url and content selector, e.g, | |
// "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id" | |
if (type === 'ajax') { | |
hrefParts = href.split(/\s+/, 2); | |
href = hrefParts.shift(); | |
selector = hrefParts.shift(); | |
} | |
} | |
if (!content) { | |
if (type === 'inline') { | |
if (href) { | |
content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7 | |
} else if (obj.isDom) { | |
content = element; | |
} | |
} else if (type === 'html') { | |
content = href; | |
} else if (!type && !href && obj.isDom) { | |
type = 'inline'; | |
content = element; | |
} | |
} | |
$.extend(obj, { | |
href : href, | |
type : type, | |
content : content, | |
title : title, | |
selector : selector | |
}); | |
group[ i ] = obj; | |
}); | |
// Extend the defaults | |
F.opts = $.extend(true, {}, F.defaults, opts); | |
// All options are merged recursive except keys | |
if (opts.keys !== undefined) { | |
F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false; | |
} | |
F.group = group; | |
return F._start(F.opts.index); | |
}, | |
// Cancel image loading or abort ajax request | |
cancel: function () { | |
var coming = F.coming; | |
if (coming && false === F.trigger('onCancel')) { | |
return; | |
} | |
F.hideLoading(); | |
if (!coming) { | |
return; | |
} | |
if (F.ajaxLoad) { | |
F.ajaxLoad.abort(); | |
} | |
F.ajaxLoad = null; | |
if (F.imgPreload) { | |
F.imgPreload.onload = F.imgPreload.onerror = null; | |
} | |
if (coming.wrap) { | |
coming.wrap.stop(true, true).trigger('onReset').remove(); | |
} | |
F.coming = null; | |
// If the first item has been canceled, then clear everything | |
if (!F.current) { | |
F._afterZoomOut( coming ); | |
} | |
}, | |
// Start closing animation if is open; remove immediately if opening/closing | |
close: function (event) { | |
F.cancel(); | |
if (false === F.trigger('beforeClose')) { | |
return; | |
} | |
F.unbindEvents(); | |
if (!F.isActive) { | |
return; | |
} | |
if (!F.isOpen || event === true) { | |
$('.fancybox-wrap').stop(true).trigger('onReset').remove(); | |
F._afterZoomOut(); | |
} else { | |
F.isOpen = F.isOpened = false; | |
F.isClosing = true; | |
$('.fancybox-item, .fancybox-nav').remove(); | |
F.wrap.stop(true, true).removeClass('fancybox-opened'); | |
F.transitions[ F.current.closeMethod ](); | |
} | |
}, | |
// Manage slideshow: | |
// $.fancybox.play(); - toggle slideshow | |
// $.fancybox.play( true ); - start | |
// $.fancybox.play( false ); - stop | |
play: function ( action ) { | |
var clear = function () { | |
clearTimeout(F.player.timer); | |
}, | |
set = function () { | |
clear(); | |
if (F.current && F.player.isActive) { | |
F.player.timer = setTimeout(F.next, F.current.playSpeed); | |
} | |
}, | |
stop = function () { | |
clear(); | |
D.unbind('.player'); | |
F.player.isActive = false; | |
F.trigger('onPlayEnd'); | |
}, | |
start = function () { | |
if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) { | |
F.player.isActive = true; | |
D.bind({ | |
'onCancel.player beforeClose.player' : stop, | |
'onUpdate.player' : set, | |
'beforeLoad.player' : clear | |
}); | |
set(); | |
F.trigger('onPlayStart'); | |
} | |
}; | |
if (action === true || (!F.player.isActive && action !== false)) { | |
start(); | |
} else { | |
stop(); | |
} | |
}, | |
// Navigate to next gallery item | |
next: function ( direction ) { | |
var current = F.current; | |
if (current) { | |
if (!isString(direction)) { | |
direction = current.direction.next; | |
} | |
F.jumpto(current.index + 1, direction, 'next'); | |
} | |
}, | |
// Navigate to previous gallery item | |
prev: function ( direction ) { | |
var current = F.current; | |
if (current) { | |
if (!isString(direction)) { | |
direction = current.direction.prev; | |
} | |
F.jumpto(current.index - 1, direction, 'prev'); | |
} | |
}, | |
// Navigate to gallery item by index | |
jumpto: function ( index, direction, router ) { | |
var current = F.current; | |
if (!current) { | |
return; | |
} | |
index = getScalar(index); | |
F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ]; | |
F.router = router || 'jumpto'; | |
if (current.loop) { | |
if (index < 0) { | |
index = current.group.length + (index % current.group.length); | |
} | |
index = index % current.group.length; | |
} | |
if (current.group[ index ] !== undefined) { | |
F.cancel(); | |
F._start(index); | |
} | |
}, | |
// Center inside viewport and toggle position type to fixed or absolute if needed | |
reposition: function (e, onlyAbsolute) { | |
var current = F.current, | |
wrap = current ? current.wrap : null, | |
pos; | |
if (wrap) { | |
pos = F._getPosition(onlyAbsolute); | |
if (e && e.type === 'scroll') { | |
delete pos.position; | |
wrap.stop(true, true).animate(pos, 200); | |
} else { | |
wrap.css(pos); | |
current.pos = $.extend({}, current.dim, pos); | |
} | |
} | |
}, | |
update: function (e) { | |
var type = (e && e.originalEvent && e.originalEvent.type), | |
anyway = !type || type === 'orientationchange'; | |
if (anyway) { | |
clearTimeout(didUpdate); | |
didUpdate = null; | |
} | |
if (!F.isOpen || didUpdate) { | |
return; | |
} | |
didUpdate = setTimeout(function() { | |
var current = F.current; | |
if (!current || F.isClosing) { | |
return; | |
} | |
F.wrap.removeClass('fancybox-tmp'); | |
if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) { | |
F._setDimension(); | |
} | |
if (!(type === 'scroll' && current.canShrink)) { | |
F.reposition(e); | |
} | |
F.trigger('onUpdate'); | |
didUpdate = null; | |
}, (anyway && !isTouch ? 0 : 300)); | |
}, | |
// Shrink content to fit inside viewport or restore if resized | |
toggle: function ( action ) { | |
if (F.isOpen) { | |
F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView; | |
// Help browser to restore document dimensions | |
if (isTouch) { | |
F.wrap.removeAttr('style').addClass('fancybox-tmp'); | |
F.trigger('onUpdate'); | |
} | |
F.update(); | |
} | |
}, | |
hideLoading: function () { | |
D.unbind('.loading'); | |
$('#fancybox-loading').remove(); | |
}, | |
showLoading: function () { | |
var el, viewport; | |
F.hideLoading(); | |
el = $(F.opts.tpl.loading).click(F.cancel).appendTo('body'); | |
// If user will press the escape-button, the request will be canceled | |
D.bind('keydown.loading', function(e) { | |
if ((e.which || e.keyCode) === 27) { | |
e.preventDefault(); | |
F.cancel(); | |
} | |
}); | |
if (!F.defaults.fixed) { | |
viewport = F.getViewport(); | |
el.css({ | |
position : 'absolute', | |
top : (viewport.h * 0.5) + viewport.y, | |
left : (viewport.w * 0.5) + viewport.x | |
}); | |
} | |
F.trigger('onLoading'); | |
}, | |
getViewport: function () { | |
var locked = (F.current && F.current.locked) || false, | |
rez = { | |
x: W.scrollLeft(), | |
y: W.scrollTop() | |
}; | |
if (locked && locked.length) { | |
rez.w = locked[0].clientWidth; | |
rez.h = locked[0].clientHeight; | |
} else { | |
// See http://bugs.jquery.com/ticket/6724 | |
rez.w = isTouch && window.innerWidth ? window.innerWidth : W.width(); | |
rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height(); | |
} | |
return rez; | |
}, | |
// Unbind the keyboard / clicking actions | |
unbindEvents: function () { | |
if (F.wrap && isQuery(F.wrap)) { | |
F.wrap.unbind('.fb'); | |
} | |
D.unbind('.fb'); | |
W.unbind('.fb'); | |
}, | |
bindEvents: function () { | |
var current = F.current, | |
keys; | |
if (!current) { | |
return; | |
} | |
// Changing document height on iOS devices triggers a 'resize' event, | |
// that can change document height... repeating infinitely | |
W.bind('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update); | |
keys = current.keys; | |
if (keys) { | |
D.bind('keydown.fb', function (e) { | |
var code = e.which || e.keyCode, | |
target = e.target || e.srcElement; | |
// Skip esc key if loading, because showLoading will cancel preloading | |
if (code === 27 && F.coming) { | |
return false; | |
} | |
// Ignore key combinations and key events within form elements | |
if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) { | |
$.each(keys, function(i, val) { | |
if (current.group.length > 1 && val[ code ] !== undefined) { | |
F[ i ]( val[ code ] ); | |
e.preventDefault(); | |
return false; | |
} | |
if ($.inArray(code, val) > -1) { | |
F[ i ] (); | |
e.preventDefault(); | |
return false; | |
} | |
}); | |
} | |
}); | |
} | |
if ($.fn.mousewheel && current.mouseWheel) { | |
F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) { | |
var target = e.target || null, | |
parent = $(target), | |
canScroll = false; | |
while (parent.length) { | |
if (canScroll || parent.is('.fancybox-skin') || parent.is('.fancybox-wrap')) { | |
break; | |
} | |
canScroll = isScrollable( parent[0] ); | |
parent = $(parent).parent(); | |
} | |
if (delta !== 0 && !canScroll) { | |
if (F.group.length > 1 && !current.canShrink) { | |
if (deltaY > 0 || deltaX > 0) { | |
F.prev( deltaY > 0 ? 'down' : 'left' ); | |
} else if (deltaY < 0 || deltaX < 0) { | |
F.next( deltaY < 0 ? 'up' : 'right' ); | |
} | |
e.preventDefault(); | |
} | |
} | |
}); | |
} | |
}, | |
trigger: function (event, o) { | |
var ret, obj = o || F.coming || F.current; | |
if (obj) { | |
if ($.isFunction( obj[event] )) { | |
ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1)); | |
} | |
if (ret === false) { | |
return false; | |
} | |
if (obj.helpers) { | |
$.each(obj.helpers, function (helper, opts) { | |
if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) { | |
F.helpers[helper][event]($.extend(true, {}, F.helpers[helper].defaults, opts), obj); | |
} | |
}); | |
} | |
} | |
D.trigger(event); | |
}, | |
isImage: function (str) { | |
return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i); | |
}, | |
isSWF: function (str) { | |
return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i); | |
}, | |
_start: function (index) { | |
var coming = {}, | |
obj, | |
href, | |
type, | |
margin, | |
padding; | |
index = getScalar( index ); | |
obj = F.group[ index ] || null; | |
if (!obj) { | |
return false; | |
} | |
coming = $.extend(true, {}, F.opts, obj); | |
// Convert margin and padding properties to array - top, right, bottom, left | |
margin = coming.margin; | |
padding = coming.padding; | |
if ($.type(margin) === 'number') { | |
coming.margin = [margin, margin, margin, margin]; | |
} | |
if ($.type(padding) === 'number') { | |
coming.padding = [padding, padding, padding, padding]; | |
} | |
// 'modal' propery is just a shortcut | |
if (coming.modal) { | |
$.extend(true, coming, { | |
closeBtn : false, | |
closeClick : false, | |
nextClick : false, | |
arrows : false, | |
mouseWheel : false, | |
keys : null, | |
helpers: { | |
overlay : { | |
closeClick : false | |
} | |
} | |
}); | |
} | |
// 'autoSize' property is a shortcut, too | |
if (coming.autoSize) { | |
coming.autoWidth = coming.autoHeight = true; | |
} | |
if (coming.width === 'auto') { | |
coming.autoWidth = true; | |
} | |
if (coming.height === 'auto') { | |
coming.autoHeight = true; | |
} | |
/* | |
* Add reference to the group, so it`s possible to access from callbacks, example: | |
* afterLoad : function() { | |
* this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : ''); | |
* } | |
*/ | |
coming.group = F.group; | |
coming.index = index; | |
// Give a chance for callback or helpers to update coming item (type, title, etc) | |
F.coming = coming; | |
if (false === F.trigger('beforeLoad')) { | |
F.coming = null; | |
return; | |
} | |
type = coming.type; | |
href = coming.href; | |
if (!type) { | |
F.coming = null; | |
//If we can not determine content type then drop silently or display next/prev item if looping through gallery | |
if (F.current && F.router && F.router !== 'jumpto') { | |
F.current.index = index; | |
return F[ F.router ]( F.direction ); | |
} | |
return false; | |
} | |
F.isActive = true; | |
if (type === 'image' || type === 'swf') { | |
coming.autoHeight = coming.autoWidth = false; | |
coming.scrolling = 'visible'; | |
} | |
if (type === 'image') { | |
coming.aspectRatio = true; | |
} | |
if (type === 'iframe' && isTouch) { | |
coming.scrolling = 'scroll'; | |
} | |
// Build the neccessary markup | |
coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' ); | |
$.extend(coming, { | |
skin : $('.fancybox-skin', coming.wrap), | |
outer : $('.fancybox-outer', coming.wrap), | |
inner : $('.fancybox-inner', coming.wrap) | |
}); | |
$.each(["Top", "Right", "Bottom", "Left"], function(i, v) { | |
coming.skin.css('padding' + v, getValue(coming.padding[ i ])); | |
}); | |
F.trigger('onReady'); | |
// Check before try to load; 'inline' and 'html' types need content, others - href | |
if (type === 'inline' || type === 'html') { | |
if (!coming.content || !coming.content.length) { | |
return F._error( 'content' ); | |
} | |
} else if (!href) { | |
return F._error( 'href' ); | |
} | |
if (type === 'image') { | |
F._loadImage(); | |
} else if (type === 'ajax') { | |
F._loadAjax(); | |
} else if (type === 'iframe') { | |
F._loadIframe(); | |
} else { | |
F._afterLoad(); | |
} | |
}, | |
_error: function ( type ) { | |
$.extend(F.coming, { | |
type : 'html', | |
autoWidth : true, | |
autoHeight : true, | |
minWidth : 0, | |
minHeight : 0, | |
scrolling : 'no', | |
hasError : type, | |
content : F.coming.tpl.error | |
}); | |
F._afterLoad(); | |
}, | |
_loadImage: function () { | |
// Reset preload image so it is later possible to check "complete" property | |
var img = F.imgPreload = new Image(); | |
img.onload = function () { | |
this.onload = this.onerror = null; | |
F.coming.width = this.width / F.opts.pixelRatio; | |
F.coming.height = this.height / F.opts.pixelRatio; | |
F._afterLoad(); | |
}; | |
img.onerror = function () { | |
this.onload = this.onerror = null; | |
F._error( 'image' ); | |
}; | |
img.src = F.coming.href; | |
if (img.complete !== true) { | |
F.showLoading(); | |
} | |
}, | |
_loadAjax: function () { | |
var coming = F.coming; | |
F.showLoading(); | |
F.ajaxLoad = $.ajax($.extend({}, coming.ajax, { | |
url: coming.href, | |
error: function (jqXHR, textStatus) { | |
if (F.coming && textStatus !== 'abort') { | |
F._error( 'ajax', jqXHR ); | |
} else { | |
F.hideLoading(); | |
} | |
}, | |
success: function (data, textStatus) { | |
if (textStatus === 'success') { | |
coming.content = data; | |
F._afterLoad(); | |
} | |
} | |
})); | |
}, | |
_loadIframe: function() { | |
var coming = F.coming, | |
iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime())) | |
.attr('scrolling', isTouch ? 'auto' : coming.iframe.scrolling) | |
.attr('src', coming.href); | |
// This helps IE | |
$(coming.wrap).bind('onReset', function () { | |
try { | |
$(this).find('iframe').hide().attr('src', '//about:blank').end().empty(); | |
} catch (e) {} | |
}); | |
if (coming.iframe.preload) { | |
F.showLoading(); | |
iframe.one('load', function() { | |
$(this).data('ready', 1); | |
// iOS will lose scrolling if we resize | |
if (!isTouch) { | |
$(this).bind('load.fb', F.update); | |
} | |
// Without this trick: | |
// - iframe won't scroll on iOS devices | |
// - IE7 sometimes displays empty iframe | |
$(this).parents('.fancybox-wrap').width('100%').removeClass('fancybox-tmp').show(); | |
F._afterLoad(); | |
}); | |
} | |
coming.content = iframe.appendTo( coming.inner ); | |
if (!coming.iframe.preload) { | |
F._afterLoad(); | |
} | |
}, | |
_preloadImages: function() { | |
var group = F.group, | |
current = F.current, | |
len = group.length, | |
cnt = current.preload ? Math.min(current.preload, len - 1) : 0, | |
item, | |
i; | |
for (i = 1; i <= cnt; i += 1) { | |
item = group[ (current.index + i ) % len ]; | |
if (item.type === 'image' && item.href) { | |
new Image().src = item.href; | |
} | |
} | |
}, | |
_afterLoad: function () { | |
var coming = F.coming, | |
previous = F.current, | |
placeholder = 'fancybox-placeholder', | |
current, | |
content, | |
type, | |
scrolling, | |
href, | |
embed; | |
F.hideLoading(); | |
if (!coming || F.isActive === false) { | |
return; | |
} | |
if (false === F.trigger('afterLoad', coming, previous)) { | |
coming.wrap.stop(true).trigger('onReset').remove(); | |
F.coming = null; | |
return; | |
} | |
if (previous) { | |
F.trigger('beforeChange', previous); | |
previous.wrap.stop(true).removeClass('fancybox-opened') | |
.find('.fancybox-item, .fancybox-nav') | |
.remove(); | |
} | |
F.unbindEvents(); | |
current = coming; | |
content = coming.content; | |
type = coming.type; | |
scrolling = coming.scrolling; | |
$.extend(F, { | |
wrap : current.wrap, | |
skin : current.skin, | |
outer : current.outer, | |
inner : current.inner, | |
current : current, | |
previous : previous | |
}); | |
href = current.href; | |
switch (type) { | |
case 'inline': | |
case 'ajax': | |
case 'html': | |
if (current.selector) { | |
content = $('<div>').html(content).find(current.selector); | |
} else if (isQuery(content)) { | |
if (!content.data(placeholder)) { | |
content.data(placeholder, $('<div class="' + placeholder + '"></div>').insertAfter( content ).hide() ); | |
} | |
content = content.show().detach(); | |
current.wrap.bind('onReset', function () { | |
if ($(this).find(content).length) { | |
content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false); | |
} | |
}); | |
} | |
break; | |
case 'image': | |
content = current.tpl.image.replace(/\{href\}/g, href); | |
break; | |
case 'swf': | |
content = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>'; | |
embed = ''; | |
$.each(current.swf, function(name, val) { | |
content += '<param name="' + name + '" value="' + val + '"></param>'; | |
embed += ' ' + name + '="' + val + '"'; | |
}); | |
content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + '></embed></object>'; | |
break; | |
} | |
if (!(isQuery(content) && content.parent().is(current.inner))) { | |
current.inner.append( content ); | |
} | |
// Give a chance for helpers or callbacks to update elements | |
F.trigger('beforeShow'); | |
// Set scrolling before calculating dimensions | |
current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling)); | |
// Set initial dimensions and start position | |
F._setDimension(); | |
F.reposition(); | |
F.isOpen = false; | |
F.coming = null; | |
F.bindEvents(); | |
if (!F.isOpened) { | |
$('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove(); | |
} else if (previous.prevMethod) { | |
F.transitions[ previous.prevMethod ](); | |
} | |
F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ](); | |
F._preloadImages(); | |
}, | |
_setDimension: function () { | |
var viewport = F.getViewport(), | |
steps = 0, | |
canShrink = false, | |
canExpand = false, | |
wrap = F.wrap, | |
skin = F.skin, | |
inner = F.inner, | |
current = F.current, | |
width = current.width, | |
height = current.height, | |
minWidth = current.minWidth, | |
minHeight = current.minHeight, | |
maxWidth = current.maxWidth, | |
maxHeight = current.maxHeight, | |
scrolling = current.scrolling, | |
scrollOut = current.scrollOutside ? current.scrollbarWidth : 0, | |
margin = current.margin, | |
wMargin = getScalar(margin[1] + margin[3]), | |
hMargin = getScalar(margin[0] + margin[2]), | |
wPadding, | |
hPadding, | |
wSpace, | |
hSpace, | |
origWidth, | |
origHeight, | |
origMaxWidth, | |
origMaxHeight, | |
ratio, | |
width_, | |
height_, | |
maxWidth_, | |
maxHeight_, | |
iframe, | |
body; | |
// Reset dimensions so we could re-check actual size | |
wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp'); | |
wPadding = getScalar(skin.outerWidth(true) - skin.width()); | |
hPadding = getScalar(skin.outerHeight(true) - skin.height()); | |
// Any space between content and viewport (margin, padding, border, title) | |
wSpace = wMargin + wPadding; | |
hSpace = hMargin + hPadding; | |
origWidth = isPercentage(width) ? (viewport.w - wSpace) * getScalar(width) / 100 : width; | |
origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height; | |
if (current.type === 'iframe') { | |
iframe = current.content; | |
if (current.autoHeight && iframe && iframe.data('ready') === 1) { | |
try { | |
if (iframe[0].contentWindow.document.location) { | |
inner.width( origWidth ).height(9999); | |
body = iframe.contents().find('body'); | |
if (scrollOut) { | |
body.css('overflow-x', 'hidden'); | |
} | |
origHeight = body.outerHeight(true); | |
} | |
} catch (e) {} | |
} | |
} else if (current.autoWidth || current.autoHeight) { | |
inner.addClass( 'fancybox-tmp' ); | |
// Set width or height in case we need to calculate only one dimension | |
if (!current.autoWidth) { | |
inner.width( origWidth ); | |
} | |
if (!current.autoHeight) { | |
inner.height( origHeight ); | |
} | |
if (current.autoWidth) { | |
origWidth = inner.width(); | |
} | |
if (current.autoHeight) { | |
origHeight = inner.height(); | |
} | |
inner.removeClass( 'fancybox-tmp' ); | |
} | |
width = getScalar( origWidth ); | |
height = getScalar( origHeight ); | |
ratio = origWidth / origHeight; | |
// Calculations for the content | |
minWidth = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth); | |
maxWidth = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth); | |
minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight); | |
maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight); | |
// These will be used to determine if wrap can fit in the viewport | |
origMaxWidth = maxWidth; | |
origMaxHeight = maxHeight; | |
if (current.fitToView) { | |
maxWidth = Math.min(viewport.w - wSpace, maxWidth); | |
maxHeight = Math.min(viewport.h - hSpace, maxHeight); | |
} | |
maxWidth_ = viewport.w - wMargin; | |
maxHeight_ = viewport.h - hMargin; | |
if (current.aspectRatio) { | |
if (width > maxWidth) { | |
width = maxWidth; | |
height = getScalar(width / ratio); | |
} | |
if (height > maxHeight) { | |
height = maxHeight; | |
width = getScalar(height * ratio); | |
} | |
if (width < minWidth) { | |
width = minWidth; | |
height = getScalar(width / ratio); | |
} | |
if (height < minHeight) { | |
height = minHeight; | |
width = getScalar(height * ratio); | |
} | |
} else { | |
width = Math.max(minWidth, Math.min(width, maxWidth)); | |
if (current.autoHeight && current.type !== 'iframe') { | |
inner.width( width ); | |
height = inner.height(); | |
} | |
height = Math.max(minHeight, Math.min(height, maxHeight)); | |
} | |
// Try to fit inside viewport (including the title) | |
if (current.fitToView) { | |
inner.width( width ).height( height ); | |
wrap.width( width + wPadding ); | |
// Real wrap dimensions | |
width_ = wrap.width(); | |
height_ = wrap.height(); | |
if (current.aspectRatio) { | |
while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) { | |
if (steps++ > 19) { | |
break; | |
} | |
height = Math.max(minHeight, Math.min(maxHeight, height - 10)); | |
width = getScalar(height * ratio); | |
if (width < minWidth) { | |
width = minWidth; | |
height = getScalar(width / ratio); | |
} | |
if (width > maxWidth) { | |
width = maxWidth; | |
height = getScalar(width / ratio); | |
} | |
inner.width( width ).height( height ); | |
wrap.width( width + wPadding ); | |
width_ = wrap.width(); | |
height_ = wrap.height(); | |
} | |
} else { | |
width = Math.max(minWidth, Math.min(width, width - (width_ - maxWidth_))); | |
height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_))); | |
} | |
} | |
if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) { | |
width += scrollOut; | |
} | |
inner.width( width ).height( height ); | |
wrap.width( width + wPadding ); | |
width_ = wrap.width(); | |
height_ = wrap.height(); | |
canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight; | |
canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight)); | |
$.extend(current, { | |
dim : { | |
width : getValue( width_ ), | |
height : getValue( height_ ) | |
}, | |
origWidth : origWidth, | |
origHeight : origHeight, | |
canShrink : canShrink, | |
canExpand : canExpand, | |
wPadding : wPadding, | |
hPadding : hPadding, | |
wrapSpace : height_ - skin.outerHeight(true), | |
skinSpace : skin.height() - height | |
}); | |
if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) { | |
inner.height('auto'); | |
} | |
}, | |
_getPosition: function (onlyAbsolute) { | |
var current = F.current, | |
viewport = F.getViewport(), | |
margin = current.margin, | |
width = F.wrap.width() + margin[1] + margin[3], | |
height = F.wrap.height() + margin[0] + margin[2], | |
rez = { | |
position: 'absolute', | |
top : margin[0], | |
left : margin[3] | |
}; | |
if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) { | |
rez.position = 'fixed'; | |
} else if (!current.locked) { | |
rez.top += viewport.y; | |
rez.left += viewport.x; | |
} | |
rez.top = getValue(Math.max(rez.top, rez.top + ((viewport.h - height) * current.topRatio))); | |
rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width) * current.leftRatio))); | |
return rez; | |
}, | |
_afterZoomIn: function () { | |
var current = F.current; | |
if (!current) { | |
return; | |
} | |
F.isOpen = F.isOpened = true; | |
F.wrap.css('overflow', 'visible').addClass('fancybox-opened').hide().show(0); | |
F.update(); | |
// Assign a click event | |
if ( current.closeClick || (current.nextClick && F.group.length > 1) ) { | |
F.inner.css('cursor', 'pointer').bind('click.fb', function(e) { | |
if (!$(e.target).is('a') && !$(e.target).parent().is('a')) { | |
e.preventDefault(); | |
F[ current.closeClick ? 'close' : 'next' ](); | |
} | |
}); | |
} | |
// Create a close button | |
if (current.closeBtn) { | |
$(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) { | |
e.preventDefault(); | |
F.close(); | |
}); | |
} | |
// Create navigation arrows | |
if (current.arrows && F.group.length > 1) { | |
if (current.loop || current.index > 0) { | |
$(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev); | |
} | |
if (current.loop || current.index < F.group.length - 1) { | |
$(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next); | |
} | |
} | |
F.trigger('afterShow'); | |
// Stop the slideshow if this is the last item | |
if (!current.loop && current.index === current.group.length - 1) { | |
F.play( false ); | |
} else if (F.opts.autoPlay && !F.player.isActive) { | |
F.opts.autoPlay = false; | |
F.play(true); | |
} | |
}, | |
_afterZoomOut: function ( obj ) { | |
obj = obj || F.current; | |
$('.fancybox-wrap').trigger('onReset').remove(); | |
$.extend(F, { | |
group : {}, | |
opts : {}, | |
router : false, | |
current : null, | |
isActive : false, | |
isOpened : false, | |
isOpen : false, | |
isClosing : false, | |
wrap : null, | |
skin : null, | |
outer : null, | |
inner : null | |
}); | |
F.trigger('afterClose', obj); | |
} | |
}); | |
/* | |
* Default transitions | |
*/ | |
F.transitions = { | |
getOrigPosition: function () { | |
var current = F.current, | |
element = current.element, | |
orig = current.orig, | |
pos = {}, | |
width = 50, | |
height = 50, | |
hPadding = current.hPadding, | |
wPadding = current.wPadding, | |
viewport = F.getViewport(); | |
if (!orig && current.isDom && element.is(':visible')) { | |
orig = element.find('img:first'); | |
if (!orig.length) { | |
orig = element; | |
} | |
} | |
if (isQuery(orig)) { | |
pos = orig.offset(); | |
if (orig.is('img')) { | |
width = orig.outerWidth(); | |
height = orig.outerHeight(); | |
} | |
} else { | |
pos.top = viewport.y + (viewport.h - height) * current.topRatio; | |
pos.left = viewport.x + (viewport.w - width) * current.leftRatio; | |
} | |
if (F.wrap.css('position') === 'fixed' || current.locked) { | |
pos.top -= viewport.y; | |
pos.left -= viewport.x; | |
} | |
pos = { | |
top : getValue(pos.top - hPadding * current.topRatio), | |
left : getValue(pos.left - wPadding * current.leftRatio), | |
width : getValue(width + wPadding), | |
height : getValue(height + hPadding) | |
}; | |
return pos; | |
}, | |
step: function (now, fx) { | |
var ratio, | |
padding, | |
value, | |
prop = fx.prop, | |
current = F.current, | |
wrapSpace = current.wrapSpace, | |
skinSpace = current.skinSpace; | |
if (prop === 'width' || prop === 'height') { | |
ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start); | |
if (F.isClosing) { | |
ratio = 1 - ratio; | |
} | |
padding = prop === 'width' ? current.wPadding : current.hPadding; | |
value = now - padding; | |
F.skin[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) ) ); | |
F.inner[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) ); | |
} | |
}, | |
zoomIn: function () { | |
var current = F.current, | |
startPos = current.pos, | |
effect = current.openEffect, | |
elastic = effect === 'elastic', | |
endPos = $.extend({opacity : 1}, startPos); | |
// Remove "position" property that breaks older IE | |
delete endPos.position; | |
if (elastic) { | |
startPos = this.getOrigPosition(); | |
if (current.openOpacity) { | |
startPos.opacity = 0.1; | |
} | |
} else if (effect === 'fade') { | |
startPos.opacity = 0.1; | |
} | |
F.wrap.css(startPos).animate(endPos, { | |
duration : effect === 'none' ? 0 : current.openSpeed, | |
easing : current.openEasing, | |
step : elastic ? this.step : null, | |
complete : F._afterZoomIn | |
}); | |
}, | |
zoomOut: function () { | |
var current = F.current, | |
effect = current.closeEffect, | |
elastic = effect === 'elastic', | |
endPos = {opacity : 0.1}; | |
if (elastic) { | |
endPos = this.getOrigPosition(); | |
if (current.closeOpacity) { | |
endPos.opacity = 0.1; | |
} | |
} | |
F.wrap.animate(endPos, { | |
duration : effect === 'none' ? 0 : current.closeSpeed, | |
easing : current.closeEasing, | |
step : elastic ? this.step : null, | |
complete : F._afterZoomOut | |
}); | |
}, | |
changeIn: function () { | |
var current = F.current, | |
effect = current.nextEffect, | |
startPos = current.pos, | |
endPos = { opacity : 1 }, | |
direction = F.direction, | |
distance = 200, | |
field; | |
startPos.opacity = 0.1; | |
if (effect === 'elastic') { | |
field = direction === 'down' || direction === 'up' ? 'top' : 'left'; | |
if (direction === 'down' || direction === 'right') { | |
startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance); | |
endPos[ field ] = '+=' + distance + 'px'; | |
} else { | |
startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance); | |
endPos[ field ] = '-=' + distance + 'px'; | |
} | |
} | |
// Workaround for http://bugs.jquery.com/ticket/12273 | |
if (effect === 'none') { | |
F._afterZoomIn(); | |
} else { | |
F.wrap.css(startPos).animate(endPos, { | |
duration : current.nextSpeed, | |
easing : current.nextEasing, | |
complete : F._afterZoomIn | |
}); | |
} | |
}, | |
changeOut: function () { | |
var previous = F.previous, | |
effect = previous.prevEffect, | |
endPos = { opacity : 0.1 }, | |
direction = F.direction, | |
distance = 200; | |
if (effect === 'elastic') { | |
endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px'; | |
} | |
previous.wrap.animate(endPos, { | |
duration : effect === 'none' ? 0 : previous.prevSpeed, | |
easing : previous.prevEasing, | |
complete : function () { | |
$(this).trigger('onReset').remove(); | |
} | |
}); | |
} | |
}; | |
/* | |
* Overlay helper | |
*/ | |
F.helpers.overlay = { | |
defaults : { | |
closeClick : true, // if true, fancyBox will be closed when user clicks on the overlay | |
speedOut : 200, // duration of fadeOut animation | |
showEarly : true, // indicates if should be opened immediately or wait until the content is ready | |
css : {}, // custom CSS properties | |
locked : !isTouch, // if true, the content will be locked into overlay | |
fixed : true // if false, the overlay CSS position property will not be set to "fixed" | |
}, | |
overlay : null, // current handle | |
fixed : false, // indicates if the overlay has position "fixed" | |
el : $('html'), // element that contains "the lock" | |
// Public methods | |
create : function(opts) { | |
var parent; | |
opts = $.extend({}, this.defaults, opts); | |
if (this.overlay) { | |
this.close(); | |
} | |
parent = F.coming ? F.coming.parent : opts.parent; | |
this.overlay = $('<div class="fancybox-overlay"></div>').appendTo( parent && parent.length ? parent : 'body' ); | |
this.fixed = false; | |
if (opts.fixed && F.defaults.fixed) { | |
this.overlay.addClass('fancybox-overlay-fixed'); | |
this.fixed = true; | |
} | |
}, | |
open : function(opts) { | |
var that = this; | |
opts = $.extend({}, this.defaults, opts); | |
if (this.overlay) { | |
this.overlay.unbind('.overlay').width('auto').height('auto'); | |
} else { | |
this.create(opts); | |
} | |
if (!this.fixed) { | |
W.bind('resize.overlay', $.proxy( this.update, this) ); | |
this.update(); | |
} | |
if (opts.closeClick) { | |
this.overlay.bind('click.overlay', function(e) { | |
if ($(e.target).hasClass('fancybox-overlay')) { | |
if (F.isActive) { | |
F.close(); | |
} else { | |
that.close(); | |
} | |
return false; | |
} | |
}); | |
} | |
this.overlay.css( opts.css ).show(); | |
}, | |
close : function() { | |
W.unbind('resize.overlay'); | |
if (this.el.hasClass('fancybox-lock')) { | |
$('.fancybox-margin').removeClass('fancybox-margin'); | |
this.el.removeClass('fancybox-lock'); | |
W.scrollTop( this.scrollV ).scrollLeft( this.scrollH ); | |
} | |
$('.fancybox-overlay').remove().hide(); | |
$.extend(this, { | |
overlay : null, | |
fixed : false | |
}); | |
}, | |
// Private, callbacks | |
update : function () { | |
var width = '100%', offsetWidth; | |
// Reset width/height so it will not mess | |
this.overlay.width(width).height('100%'); | |
// jQuery does not return reliable result for IE | |
if (IE) { | |
offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth); | |
if (D.width() > offsetWidth) { | |
width = D.width(); | |
} | |
} else if (D.width() > W.width()) { | |
width = D.width(); | |
} | |
this.overlay.width(width).height(D.height()); | |
}, | |
// This is where we can manipulate DOM, because later it would cause iframes to reload | |
onReady : function (opts, obj) { | |
var overlay = this.overlay; | |
$('.fancybox-overlay').stop(true, true); | |
if (!overlay) { | |
this.create(opts); | |
} | |
if (opts.locked && this.fixed && obj.fixed) { | |
obj.locked = this.overlay.append( obj.wrap ); | |
obj.fixed = false; | |
} | |
if (opts.showEarly === true) { | |
this.beforeShow.apply(this, arguments); | |
} | |
}, | |
beforeShow : function(opts, obj) { | |
if (obj.locked && !this.el.hasClass('fancybox-lock')) { | |
if (this.fixPosition !== false) { | |
$('*:not(object)').filter(function(){ | |
return ($(this).css('position') === 'fixed' && !$(this).hasClass("fancybox-overlay") && !$(this).hasClass("fancybox-wrap") ); | |
}).addClass('fancybox-margin'); | |
} | |
this.el.addClass('fancybox-margin'); | |
this.scrollV = W.scrollTop(); | |
this.scrollH = W.scrollLeft(); | |
this.el.addClass('fancybox-lock'); | |
W.scrollTop( this.scrollV ).scrollLeft( this.scrollH ); | |
} | |
this.open(opts); | |
}, | |
onUpdate : function() { | |
if (!this.fixed) { | |
this.update(); | |
} | |
}, | |
afterClose: function (opts) { | |
// Remove overlay if exists and fancyBox is not opening | |
// (e.g., it is not being open using afterClose callback) | |
if (this.overlay && !F.coming) { | |
this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this )); | |
} | |
} | |
}; | |
/* | |
* Title helper | |
*/ | |
F.helpers.title = { | |
defaults : { | |
type : 'float', // 'float', 'inside', 'outside' or 'over', | |
position : 'bottom' // 'top' or 'bottom' | |
}, | |
beforeShow: function (opts) { | |
var current = F.current, | |
text = current.title, | |
type = opts.type, | |
title, | |
target; | |
if ($.isFunction(text)) { | |
text = text.call(current.element, current); | |
} | |
if (!isString(text) || $.trim(text) === '') { | |
return; | |
} | |
title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">' + text + '</div>'); | |
switch (type) { | |
case 'inside': | |
target = F.skin; | |
break; | |
case 'outside': | |
target = F.wrap; | |
break; | |
case 'over': | |
target = F.inner; | |
break; | |
default: // 'float' | |
target = F.skin; | |
title.appendTo('body'); | |
if (IE) { | |
title.width( title.width() ); | |
} | |
title.wrapInner('<span class="child"></span>'); | |
//Increase bottom margin so this title will also fit into viewport | |
F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) ); | |
break; | |
} | |
title[ (opts.position === 'top' ? 'prependTo' : 'appendTo') ](target); | |
} | |
}; | |
// jQuery plugin initialization | |
$.fn.fancybox = function (options) { | |
var index, | |
that = $(this), | |
selector = this.selector || '', | |
run = function(e) { | |
var what = $(this).blur(), idx = index, relType, relVal; | |
if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) { | |
relType = options.groupAttr || 'data-fancybox-group'; | |
relVal = what.attr(relType); | |
if (!relVal) { | |
relType = 'rel'; | |
relVal = what.get(0)[ relType ]; | |
} | |
if (relVal && relVal !== '' && relVal !== 'nofollow') { | |
what = selector.length ? $(selector) : that; | |
what = what.filter('[' + relType + '="' + relVal + '"]'); | |
idx = what.index(this); | |
} | |
options.index = idx; | |
// Stop an event from bubbling if everything is fine | |
if (F.open(what, options) !== false) { | |
e.preventDefault(); | |
} | |
} | |
}; | |
options = options || {}; | |
index = options.index || 0; | |
if (!selector || options.live === false) { | |
that.unbind('click.fb-start').bind('click.fb-start', run); | |
} else { | |
D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run); | |
} | |
this.filter('[data-fancybox-start=1]').trigger('click'); | |
return this; | |
}; | |
// Tests that need a body at doc ready | |
D.ready(function() { | |
var w1, w2; | |
if ( $.scrollbarWidth === undefined ) { | |
// http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth | |
$.scrollbarWidth = function() { | |
var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'), | |
child = parent.children(), | |
width = child.innerWidth() - child.height( 99 ).innerWidth(); | |
parent.remove(); | |
return width; | |
}; | |
} | |
if ( $.support.fixedPosition === undefined ) { | |
$.support.fixedPosition = (function() { | |
var elem = $('<div style="position:fixed;top:20px;"></div>').appendTo('body'), | |
fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 ); | |
elem.remove(); | |
return fixed; | |
}()); | |
} | |
$.extend(F.defaults, { | |
scrollbarWidth : $.scrollbarWidth(), | |
fixed : $.support.fixedPosition, | |
parent : $('body') | |
}); | |
//Get real width of page scroll-bar | |
w1 = $(window).width(); | |
H.addClass('fancybox-lock-test'); | |
w2 = $(window).width(); | |
H.removeClass('fancybox-lock-test'); | |
$("<style type='text/css'>.fancybox-margin{margin-right:" + (w2 - w1) + "px;}</style>").appendTo("head"); | |
}); | |
}(window, document, jQuery)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment