2 * FancyBox - jQuery Plugin
3 * Simple and fancy lightbox alternative
5 * Examples and documentation at: http://fancybox.net
7 * Copyright (c) 2008 - 2010 Janis Skarnelis
8 * That said, it is hardly a one-person project. Many people have submitted bugs, code, and offered their advice freely. Their support is greatly appreciated.
10 * Version: 1.3.4 (11/11/2010)
11 * Requires: jQuery v1.3+
13 * Dual licensed under the MIT and GPL licenses:
14 * http://www.opensource.org/licenses/mit-license.php
15 * http://www.gnu.org/licenses/gpl.html
19 var m
, t
, u
, f
, D
, j
, E
, n
, z
, A
, q
= 0,
25 J
= /\.(jpg|gif|png|bmp|jpeg)(.*)?$/i,
26 W
= /[^\.]\.(swf)\s*$/i,
31 B
= b
.extend(b("<div/>")[0], {
34 M
= b
.browser
.msie
&& b
.browser
.version
< 7 && !window
.XMLHttpRequest
,
37 v
.onerror
= v
.onload
= null;
41 if (false === e
.onError(o
, q
, e
)) {
48 m
.html('<p id="fancybox-error">The requested content cannot be loaded.<br />Please try again later.</p>');
55 e
= b
.extend({}, b
.fn
.fancybox
.defaults
, typeof b(a
).data("fancybox") == "undefined" ? e
: b(a
).data("fancybox"));
56 w
= e
.onStart(o
, q
, e
);
57 if (w
=== false) h
= false;
59 if (typeof w
== "object") e
= b
.extend(e
, w
);
60 k
= e
.title
|| (a
.nodeName
? b(a
).attr("title") : a
.title
) || "";
61 if (a
.nodeName
&& !e
.orig
) e
.orig
= b(a
).children("img:first").length
? b(a
).children("img:first") : b(a
);
62 if (k
=== "" && e
.orig
&& e
.titleFromAlt
) k
= e
.orig
.attr("alt");
63 c
= e
.href
|| (a
.nodeName
? b(a
).attr("href") : a
.href
) || null;
64 if (/^(?:javascript)/i.test(c
) ||
69 } else if (e
.content
) g
= "html";
70 else if (c
) g
= c
.match(J
) ? "image" : c
.match(W
) ? "swf" : b(a
).hasClass("iframe") ? "iframe" : c
.indexOf("#") === 0 ? "inline" : "ajax";
73 a
= c
.substr(c
.indexOf("#"));
74 g
= b(a
).length
> 0 ? "inline" : "ajax"
80 if (e
.type
== "html" || e
.type
== "inline" || e
.type
== "ajax") {
83 } else e
.autoDimensions
= false;
86 e
.hideOnOverlayClick
= false;
87 e
.hideOnContentClick
=
89 e
.enableEscapeButton
= false;
90 e
.showCloseButton
= false
92 e
.padding
= parseInt(e
.padding
, 10);
93 e
.margin
= parseInt(e
.margin
, 10);
94 m
.css("padding", e
.padding
+ e
.margin
);
95 b(".fancybox-inline-tmp").unbind("fancybox-cancel").bind("fancybox-change", function () {
96 b(this).replaceWith(j
.children())
104 if (b(a
).parent().is("#fancybox-content") === true) {
108 b('<div class="fancybox-inline-tmp" />').hide().insertBefore(b(a
)).bind("fancybox-cleanup", function () {
109 b(this).replaceWith(j
.children())
110 }).bind("fancybox-cancel",
112 b(this).replaceWith(m
.children())
119 b
.fancybox
.showActivity();
121 v
.onerror = function () {
124 v
.onload = function () {
126 v
.onerror
= v
.onload
= null;
140 C
= '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="' + e
.width
+ '" height="' + e
.height
+ '"><param name="movie" value="' + c
+
143 b
.each(e
.swf
, function (x
, H
) {
144 C
+= '<param name="' + x
+ '" value="' + H
+ '"></param>';
145 P
+= " " + x
+ '="' + H
+ '"'
147 C
+= '<embed src="' + c
+ '" type="application/x-shockwave-flash" width="' + e
.width
+ '" height="' + e
.height
+ '"' + P
+ "></embed></object>";
153 b
.fancybox
.showActivity();
154 e
.ajax
.win
= e
.ajax
.success
;
155 G
= b
.ajax(b
.extend({}, e
.ajax
, {
157 data
: e
.ajax
.data
|| {},
158 error: function (x
) {
161 success: function (x
, H
, R
) {
162 if ((typeof R
== "object" ? R
: G
).status
== 200) {
163 if (typeof e
.ajax
.win
==
165 w
= e
.ajax
.win(c
, x
, H
, R
);
169 } else if (typeof w
== "string" || typeof w
== "object") x
= w
185 a
= a
.toString().indexOf("%") > -1 ? parseInt((b(window
).width() - e
.margin
* 2) * parseFloat(a
) / 100, 10) + "px" : a
== "auto" ? "auto" : a
+ "px";
186 c
= c
.toString().indexOf("%") > -1 ? parseInt((b(window
).height() - e
.margin
* 2) * parseFloat(c
) / 100, 10) + "px" : c
== "auto" ? "auto" : c
+ "px";
187 m
.wrapInner('<div style="width:' + a
+ ";height:" + c
+
188 ";overflow: " + (e
.scrolling
== "auto" ? "auto" : e
.scrolling
== "yes" ? "scroll" : "hidden") + ';position:relative;"></div>');
190 e
.height
= m
.height();
195 if (f
.is(":visible") && false === d
.onCleanup(l
, p
, d
)) {
196 b
.event
.trigger("fancybox-cancel");
200 b(j
.add(u
)).unbind();
201 b(window
).unbind("resize.fb scroll.fb");
202 b(document
).unbind("keydown.fb");
203 f
.is(":visible") && d
.titlePosition
!== "outside" && f
.css("height", f
.height());
209 "background-color": d
.overlayColor
,
210 opacity
: d
.overlayOpacity
,
211 cursor
: d
.hideOnOverlayClick
? "pointer" : "auto",
212 height
: b(document
).height()
214 if (!u
.is(":visible")) {
215 M
&& b("select:not(#fancybox-tmp select)").filter(function () {
216 return this.style
.visibility
!== "hidden"
219 }).one("fancybox-cleanup", function () {
220 this.style
.visibility
= "inherit"
228 n
.empty().removeAttr("style").removeClass();
229 if (d
.titleShow
!== false) {
230 if (b
.isFunction(d
.titleFormat
)) a
= d
.titleFormat(s
, l
, p
, d
);
231 else a
= s
&& s
.length
?
232 d
.titlePosition
== "float" ? '<table id="fancybox-title-float-wrap" cellpadding="0" cellspacing="0"><tr><td id="fancybox-title-float-left"></td><td id="fancybox-title-float-main">' + s
+ '</td><td id="fancybox-title-float-right"></td></tr></table>' : '<div id="fancybox-title-' + d
.titlePosition
+ '">' + s
+ "</div>" : false;
234 if (!(!s
|| s
=== "")) {
235 n
.addClass("fancybox-title-" + d
.titlePosition
).html(s
).appendTo("body").show();
236 switch (d
.titlePosition
) {
239 width
: i
.width
- d
.padding
* 2,
240 marginLeft
: d
.padding
,
241 marginRight
: d
.padding
243 y
= n
.outerHeight(true);
249 marginLeft
: d
.padding
,
250 width
: i
.width
- d
.padding
* 2,
255 n
.css("left", parseInt((n
.width() - i
.width
- 40) / 2, 10) * -1).appendTo(f
);
259 width
: i
.width
- d
.padding
* 2,
260 paddingLeft
: d
.padding
,
261 paddingRight
: d
.padding
267 if (f
.is(":visible")) {
268 b(E
.add(z
).add(A
)).hide();
276 c
= r
.width
== i
.width
&& r
.height
==
278 j
.fadeTo(d
.changeFade
, 0.3, function () {
279 var g = function () {
280 j
.html(m
.contents()).fadeTo(d
.changeFade
, 1, S
)
282 b
.event
.trigger("fancybox-change");
283 j
.empty().removeAttr("filter").css({
284 "border-width": d
.padding
,
285 width
: i
.width
- d
.padding
* 2,
286 height
: e
.autoDimensions
? "auto" : i
.height
- y
- d
.padding
* 2
294 duration
: d
.changeSpeed
,
295 easing
: d
.easingChange
,
302 f
.removeAttr("style");
303 j
.css("border-width", d
.padding
);
304 if (d
.transitionIn
== "elastic") {
306 j
.html(m
.contents());
308 if (d
.opacity
) i
.opacity
= 0;
319 d
.titlePosition
== "inside" && y
> 0 && n
.show();
321 width
: i
.width
- d
.padding
* 2,
322 height
: e
.autoDimensions
? "auto" : i
.height
- y
- d
.padding
* 2
323 }).html(m
.contents());
324 f
.css(i
).fadeIn(d
.transitionIn
== "none" ? 0 : d
.speedIn
, S
)
329 if (d
.enableEscapeButton
|| d
.enableKeyboardNav
) b(document
).bind("keydown.fb", function (a
) {
330 if (a
.keyCode
== 27 && d
.enableEscapeButton
) {
333 } else if ((a
.keyCode
==
334 37 || a
.keyCode
== 39) && d
.enableKeyboardNav
&& a
.target
.tagName
!== "INPUT" && a
.target
.tagName
!== "TEXTAREA" && a
.target
.tagName
!== "SELECT") {
336 b
.fancybox
[a
.keyCode
== 37 ? "prev" : "next"]()
339 if (d
.showNavArrows
) {
340 if (d
.cyclic
&& l
.length
> 1 || p
!== 0) z
.show();
341 if (d
.cyclic
&& l
.length
> 1 || p
!= l
.length
- 1) A
.show()
347 if (!b
.support
.opacity
) {
348 j
.get(0).style
.removeAttribute("filter");
349 f
.get(0).style
.removeAttribute("filter")
351 e
.autoDimensions
&& j
.css("height", "auto");
352 f
.css("height", "auto");
353 s
&& s
.length
&& n
.show();
354 d
.showCloseButton
&& E
.show();
356 d
.hideOnContentClick
&& j
.bind("click", b
.fancybox
.close
);
357 d
.hideOnOverlayClick
&& u
.bind("click", b
.fancybox
.close
);
358 b(window
).bind("resize.fb", b
.fancybox
.resize
);
359 d
.centerOnScroll
&& b(window
).bind("scroll.fb", b
.fancybox
.center
);
360 if (d
.type
== "iframe") b('<iframe id="fancybox-frame" name="fancybox-frame' + (new Date
).getTime() + '" frameborder="0" hspace="0" ' + (b
.browser
.msie
? 'allowtransparency="true""' : "") + ' scrolling="' + e
.scrolling
+ '" src="' + d
.href
+ '"></iframe>').appendTo(j
);
364 d
.onComplete(l
, p
, d
);
366 if (l
.length
- 1 > p
) {
368 if (typeof a
!== "undefined" && a
.match(J
)) {
375 if (typeof a
!== "undefined" && a
.match(J
)) {
380 }, T = function (a
) {
382 width
: parseInt(r
.width
+ (i
.width
- r
.width
) * a
, 10),
383 height
: parseInt(r
.height
+ (i
.height
- r
.height
) * a
, 10),
384 top
: parseInt(r
.top
+ (i
.top
- r
.top
) * a
, 10),
385 left
: parseInt(r
.left
+ (i
.left
- r
.left
) * a
, 10)
387 if (typeof i
.opacity
!== "undefined") c
.opacity
= a
< 0.5 ? 0.5 : a
;
390 width
: c
.width
- d
.padding
* 2,
391 height
: c
.height
- y
* a
- d
.padding
* 2
394 return [b(window
).width() - d
.margin
* 2, b(window
).height() - d
.margin
* 2, b(document
).scrollLeft() + d
.margin
, b(document
).scrollTop() + d
.margin
]
397 c
= {}, g
= d
.autoScale
,
399 c
.width
= d
.width
.toString().indexOf("%") > -1 ? parseInt(a
[0] * parseFloat(d
.width
) / 100, 10) : d
.width
+ k
;
400 c
.height
= d
.height
.toString().indexOf("%") > -1 ? parseInt(a
[1] * parseFloat(d
.height
) / 100, 10) : d
.height
+ k
;
401 if (g
&& (c
.width
> a
[0] || c
.height
> a
[1]))
403 "image" || e
.type
== "swf") {
404 g
= d
.width
/ d
.height
;
405 if (c
.width
> a
[0]) {
407 c
.height
= parseInt((c
.width
- k
) / g
+ k
, 10)
409 if (c
.height
> a
[1]) {
411 c
.width
= parseInt((c
.height
- k
) * g
+ k
, 10)
414 c
.width
= Math
.min(c
.width
, a
[0]);
415 c
.height
= Math
.min(c
.height
, a
[1])
417 c
.top
= parseInt(Math
.max(a
[3] - 20, a
[3] + (a
[1] - c
.height
- 40) * 0.5), 10);
418 c
.left
= parseInt(Math
.max(a
[2] - 20, a
[2] + (a
[0] - c
.width
- 40) * 0.5), 10);
421 var a
= e
.orig
? b(e
.orig
) : false,
425 c
.top
+= parseInt(a
.css("paddingTop"),
427 c
.left
+= parseInt(a
.css("paddingLeft"), 10) || 0;
428 c
.top
+= parseInt(a
.css("border-top-width"), 10) || 0;
429 c
.left
+= parseInt(a
.css("border-left-width"), 10) || 0;
431 c
.height
= a
.height();
433 width
: c
.width
+ d
.padding
* 2,
434 height
: c
.height
+ d
.padding
* 2,
435 top
: c
.top
- d
.padding
- 20,
436 left
: c
.left
- d
.padding
- 20
441 width
: d
.padding
* 2,
442 height
: d
.padding
* 2,
443 top
: parseInt(a
[3] + a
[1] * 0.5, 10),
444 left
: parseInt(a
[2] + a
[0] * 0.5, 10)
449 if (t
.is(":visible")) {
450 b("div", t
).css("top", L
* -40 + "px");
452 } else clearInterval(K
)
454 b
.fn
.fancybox = function (a
) {
455 if (!b(this).length
) return this;
456 b(this).data("fancybox", b
.extend({}, a
, b
.metadata
? b(this).metadata() : {})).unbind("click.fb").bind("click.fb", function (c
) {
463 c
= b(this).attr("rel") || "";
464 if (!c
|| c
== "" || c
=== "nofollow") o
.push(this);
466 o
= b("a[rel=" + c
+ "], area[rel=" + c
+ "]");
474 b
.fancybox = function (a
, c
) {
478 g
= typeof c
!== "undefined" ? c
: {};
480 q
= parseInt(g
.index
, 10) || 0;
483 0, C
= a
.length
; k
< C
; k
++)
484 if (typeof a
[k
] == "object") b(a
[k
]).data("fancybox", b
.extend({}, g
, a
[k
]));
485 else a
[k
] = b({}).data("fancybox", b
.extend({
488 o
= jQuery
.merge(o
, a
)
490 if (typeof a
== "object") b(a
).data("fancybox", b
.extend({}, g
, a
));
491 else a
= b({}).data("fancybox", b
.extend({
495 } if (q
> o
.length
|| q
< 0) q
= 0;
499 b
.fancybox
.showActivity = function () {
502 K
= setInterval(Z
, 66)
504 b
.fancybox
.hideActivity = function () {
507 b
.fancybox
.next = function () {
508 return b
.fancybox
.pos(p
+
511 b
.fancybox
.prev = function () {
512 return b
.fancybox
.pos(p
- 1)
514 b
.fancybox
.pos = function (a
) {
518 if (a
> -1 && a
< l
.length
) {
521 } else if (d
.cyclic
&& l
.length
> 1) {
522 q
= a
>= l
.length
? 0 : l
.length
- 1;
527 b
.fancybox
.cancel = function () {
530 b
.event
.trigger("fancybox-cancel");
536 b
.fancybox
.close = function () {
541 b
.event
.trigger("fancybox-cleanup");
549 if (!(h
|| f
.is(":hidden"))) {
552 if (d
&& false === d
.onCleanup(l
, p
, d
)) h
= false;
555 b(E
.add(z
).add(A
)).hide();
556 b(j
.add(u
)).unbind();
557 b(window
).unbind("resize.fb scroll.fb");
558 b(document
).unbind("keydown.fb");
559 j
.find("iframe").attr("src", M
&& /^https/i.test(window
.location
.href
|| "") ? "javascript:void(false)" : "about:blank");
560 d
.titlePosition
!== "inside" && n
.empty();
562 if (d
.transitionOut
== "elastic") {
564 var c
= f
.position();
571 if (d
.opacity
) i
.opacity
= 1;
577 duration
: d
.speedOut
,
582 } else f
.fadeOut(d
.transitionOut
== "none" ? 0 : d
.speedOut
, a
)
586 b
.fancybox
.resize = function () {
587 u
.is(":visible") && u
.css("height", b(document
).height());
588 b
.fancybox
.center(true)
590 b
.fancybox
.center = function (a
) {
593 g
= a
=== true ? 1 : 0;
595 !g
&& (f
.width() > c
[0] || f
.height() > c
[1]) || f
.stop().animate({
596 top
: parseInt(Math
.max(c
[3] - 20, c
[3] + (c
[1] - j
.height() - 100) * 0.5 - d
.padding
)),
597 left
: parseInt(Math
.max(c
[2] - 20, c
[2] + (c
[0] - j
.width() - 40) * 0.5 -
599 }, typeof a
== "number" ? a
: 200)
602 b
.fancybox
.init = function () {
603 if (!b("#fancybox-wrap").length
) {
604 b("body").append(m
= b('<div id="fancybox-tmp"></div>'), t
= b('<div id="fancybox-loading"><div></div></div>'), u
= b('<div id="fancybox-overlay"></div>'), f
= b('<div id="fancybox-wrap"></div>'));
605 D
= b('<div id="fancybox-outer"></div>').append('<div class="fancybox-bg" id="fancybox-bg-n"></div><div class="fancybox-bg" id="fancybox-bg-ne"></div><div class="fancybox-bg" id="fancybox-bg-e"></div><div class="fancybox-bg" id="fancybox-bg-se"></div><div class="fancybox-bg" id="fancybox-bg-s"></div><div class="fancybox-bg" id="fancybox-bg-sw"></div><div class="fancybox-bg" id="fancybox-bg-w"></div><div class="fancybox-bg" id="fancybox-bg-nw"></div>').appendTo(f
);
606 D
.append(j
= b('<div id="fancybox-content"></div>'), E
= b('<a id="fancybox-close"></a>'), n
= b('<div id="fancybox-title"></div>'), z
= b('<a href="javascript:;" id="fancybox-left"><span class="fancy-ico" id="fancybox-left-ico"></span></a>'), A
= b('<a href="javascript:;" id="fancybox-right"><span class="fancy-ico" id="fancybox-right-ico"></span></a>'));
607 E
.click(b
.fancybox
.close
);
608 t
.click(b
.fancybox
.cancel
);
609 z
.click(function (a
) {
613 A
.click(function (a
) {
617 b
.fn
.mousewheel
&& f
.bind("mousewheel.fb", function (a
, c
) {
618 if (h
) a
.preventDefault();
619 else if (b(a
.target
).get(0).clientHeight
== 0 || b(a
.target
).get(0).scrollHeight
=== b(a
.target
).get(0).clientHeight
) {
621 b
.fancybox
[c
> 0 ? "prev" : "next"]()
624 b
.support
.opacity
|| f
.addClass("fancybox-ie");
626 t
.addClass("fancybox-ie6");
627 f
.addClass("fancybox-ie6");
628 b('<iframe id="fancybox-hide-sel-frame" src="' + (/^https/i.test(window
.location
.href
|| "") ? "javascript:void(false)" : "about:blank") + '" scrolling="no" border="0" frameborder="0" tabindex="-1"></iframe>').prependTo(D
)
632 b
.fn
.fancybox
.defaults
= {
642 autoDimensions
: true,
643 centerOnScroll
: false,
648 hideOnOverlayClick
: true,
649 hideOnContentClick
: false,
652 overlayColor
: "#777",
654 titlePosition
: "float",
657 transitionIn
: "fade",
658 transitionOut
: "fade",
665 showCloseButton
: true,
667 enableEscapeButton
: true,
668 enableKeyboardNav
: true,
669 onStart: function () {},
670 onCancel: function () {},
671 onComplete: function () {},
672 onCleanup: function () {},
673 onClosed: function () {},
674 onError: function () {}
676 b(document
).ready(function () {