facebox.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /*
  2. * Facebox (for jQuery)
  3. * version: 1.3
  4. * @requires jQuery v1.2 or later
  5. * @homepage https://github.com/defunkt/facebox
  6. *
  7. * Licensed under the MIT:
  8. * http://www.opensource.org/licenses/mit-license.php
  9. *
  10. * Copyright Forever Chris Wanstrath, Kyle Neath
  11. *
  12. * Usage:
  13. *
  14. * jQuery(document).ready(function() {
  15. * jQuery('a[rel*=facebox]').facebox()
  16. * })
  17. *
  18. * <a href="#terms" rel="facebox">Terms</a>
  19. * Loads the #terms div in the box
  20. *
  21. * <a href="terms.html" rel="facebox">Terms</a>
  22. * Loads the terms.html page in the box
  23. *
  24. * <a href="terms.png" rel="facebox">Terms</a>
  25. * Loads the terms.png image in the box
  26. *
  27. *
  28. * You can also use it programmatically:
  29. *
  30. * jQuery.facebox('some html')
  31. * jQuery.facebox('some html', 'my-groovy-style')
  32. *
  33. * The above will open a facebox with "some html" as the content.
  34. *
  35. * jQuery.facebox(function($) {
  36. * $.get('blah.html', function(data) { $.facebox(data) })
  37. * })
  38. *
  39. * The above will show a loading screen before the passed function is called,
  40. * allowing for a better ajaxy experience.
  41. *
  42. * The facebox function can also display an ajax page, an image, or the contents of a div:
  43. *
  44. * jQuery.facebox({ ajax: 'remote.html' })
  45. * jQuery.facebox({ ajax: 'remote.html' }, 'my-groovy-style')
  46. * jQuery.facebox({ image: 'stairs.jpg' })
  47. * jQuery.facebox({ image: 'stairs.jpg' }, 'my-groovy-style')
  48. * jQuery.facebox({ div: '#box' })
  49. * jQuery.facebox({ div: '#box' }, 'my-groovy-style')
  50. *
  51. * Want to close the facebox? Trigger the 'close.facebox' document event:
  52. *
  53. * jQuery(document).trigger('close.facebox')
  54. *
  55. * Facebox also has a bunch of other hooks:
  56. *
  57. * loading.facebox
  58. * beforeReveal.facebox
  59. * reveal.facebox (aliased as 'afterReveal.facebox')
  60. * init.facebox
  61. * afterClose.facebox
  62. *
  63. * Simply bind a function to any of these hooks:
  64. *
  65. * $(document).bind('reveal.facebox', function() { ...stuff to do after the facebox and contents are revealed... })
  66. *
  67. */
  68. (function($) {
  69. $.facebox = function(data, klass) {
  70. $.facebox.loading()
  71. if (data.ajax) fillFaceboxFromAjax(data.ajax, klass)
  72. else if (data.image) fillFaceboxFromImage(data.image, klass)
  73. else if (data.div) fillFaceboxFromHref(data.div, klass)
  74. else if ($.isFunction(data)) data.call($)
  75. else $.facebox.reveal(data, klass)
  76. }
  77. /*
  78. * Public, $.facebox methods
  79. */
  80. $.extend($.facebox, {
  81. settings: {
  82. opacity : 0.2,
  83. overlay : true,
  84. loadingImage : '/facebox/loading.gif',
  85. closeImage : '/facebox/closelabel.png',
  86. imageTypes : [ 'png', 'jpg', 'jpeg', 'gif' ],
  87. faceboxHtml : '\
  88. <div id="facebox" style="display:none;"> \
  89. <div class="popup"> \
  90. <div class="content"> \
  91. </div> \
  92. <a href="#" class="close"></a> \
  93. </div> \
  94. </div>'
  95. },
  96. loading: function() {
  97. init()
  98. if ($('#facebox .loading').length == 1) return true
  99. showOverlay()
  100. $('#facebox .content').empty().
  101. append('<div class="loading"><img src="'+$.facebox.settings.loadingImage+'"/></div>')
  102. $('#facebox').show().css({
  103. top: getPageScroll()[1] + (getPageHeight() / 10),
  104. left: $(window).width() / 2 - ($('#facebox .popup').outerWidth() / 2)
  105. })
  106. $(document).bind('keydown.facebox', function(e) {
  107. if (e.keyCode == 27) $.facebox.close()
  108. return true
  109. })
  110. $(document).trigger('loading.facebox')
  111. },
  112. reveal: function(data, klass) {
  113. $(document).trigger('beforeReveal.facebox')
  114. if (klass) $('#facebox .content').addClass(klass)
  115. $('#facebox .content').empty().append(data)
  116. $('#facebox .popup').children().fadeIn('normal')
  117. $('#facebox').css('left', $(window).width() / 2 - ($('#facebox .popup').outerWidth() / 2))
  118. $(document).trigger('reveal.facebox').trigger('afterReveal.facebox')
  119. },
  120. close: function() {
  121. $(document).trigger('close.facebox')
  122. return false
  123. }
  124. })
  125. /*
  126. * Public, $.fn methods
  127. */
  128. $.fn.facebox = function(settings) {
  129. if ($(this).length == 0) return
  130. init(settings)
  131. function clickHandler() {
  132. $.facebox.loading(true)
  133. // support for rel="facebox.inline_popup" syntax, to add a class
  134. // also supports deprecated "facebox[.inline_popup]" syntax
  135. var klass = this.rel.match(/facebox\[?\.(\w+)\]?/)
  136. if (klass) klass = klass[1]
  137. fillFaceboxFromHref(this.href, klass)
  138. return false
  139. }
  140. return this.bind('click.facebox', clickHandler)
  141. }
  142. /*
  143. * Private methods
  144. */
  145. // called one time to setup facebox on this page
  146. function init(settings) {
  147. if ($.facebox.settings.inited) return true
  148. else $.facebox.settings.inited = true
  149. $(document).trigger('init.facebox')
  150. makeCompatible()
  151. var imageTypes = $.facebox.settings.imageTypes.join('|')
  152. $.facebox.settings.imageTypesRegexp = new RegExp('\\.(' + imageTypes + ')(\\?.*)?$', 'i')
  153. if (settings) $.extend($.facebox.settings, settings)
  154. $('body').append($.facebox.settings.faceboxHtml)
  155. var preload = [ new Image(), new Image() ]
  156. preload[0].src = $.facebox.settings.closeImage
  157. preload[1].src = $.facebox.settings.loadingImage
  158. $('#facebox').find('.b:first, .bl').each(function() {
  159. preload.push(new Image())
  160. preload.slice(-1).src = $(this).css('background-image').replace(/url\((.+)\)/, '$1')
  161. })
  162. $('#facebox .close')
  163. .click($.facebox.close)
  164. .append('<img src="'
  165. + $.facebox.settings.closeImage
  166. + '" class="close_image" title="close">')
  167. }
  168. // getPageScroll() by quirksmode.com
  169. function getPageScroll() {
  170. var xScroll, yScroll;
  171. if (self.pageYOffset) {
  172. yScroll = self.pageYOffset;
  173. xScroll = self.pageXOffset;
  174. } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
  175. yScroll = document.documentElement.scrollTop;
  176. xScroll = document.documentElement.scrollLeft;
  177. } else if (document.body) {// all other Explorers
  178. yScroll = document.body.scrollTop;
  179. xScroll = document.body.scrollLeft;
  180. }
  181. return new Array(xScroll,yScroll)
  182. }
  183. // Adapted from getPageSize() by quirksmode.com
  184. function getPageHeight() {
  185. var windowHeight
  186. if (self.innerHeight) { // all except Explorer
  187. windowHeight = self.innerHeight;
  188. } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
  189. windowHeight = document.documentElement.clientHeight;
  190. } else if (document.body) { // other Explorers
  191. windowHeight = document.body.clientHeight;
  192. }
  193. return windowHeight
  194. }
  195. // Backwards compatibility
  196. function makeCompatible() {
  197. var $s = $.facebox.settings
  198. $s.loadingImage = $s.loading_image || $s.loadingImage
  199. $s.closeImage = $s.close_image || $s.closeImage
  200. $s.imageTypes = $s.image_types || $s.imageTypes
  201. $s.faceboxHtml = $s.facebox_html || $s.faceboxHtml
  202. }
  203. // Figures out what you want to display and displays it
  204. // formats are:
  205. // div: #id
  206. // image: blah.extension
  207. // ajax: anything else
  208. function fillFaceboxFromHref(href, klass) {
  209. // div
  210. if (href.match(/#/)) {
  211. var url = window.location.href.split('#')[0]
  212. var target = href.replace(url,'')
  213. if (target == '#') return
  214. $.facebox.reveal($(target).html(), klass)
  215. // image
  216. } else if (href.match($.facebox.settings.imageTypesRegexp)) {
  217. fillFaceboxFromImage(href, klass)
  218. // ajax
  219. } else {
  220. fillFaceboxFromAjax(href, klass)
  221. }
  222. }
  223. function fillFaceboxFromImage(href, klass) {
  224. var image = new Image()
  225. image.onload = function() {
  226. $.facebox.reveal('<div class="image"><img src="' + image.src + '" /></div>', klass)
  227. }
  228. image.src = href
  229. }
  230. function fillFaceboxFromAjax(href, klass) {
  231. $.get(href, function(data) { $.facebox.reveal(data, klass) })
  232. }
  233. function skipOverlay() {
  234. return $.facebox.settings.overlay == false || $.facebox.settings.opacity === null
  235. }
  236. function showOverlay() {
  237. if (skipOverlay()) return
  238. if ($('#facebox_overlay').length == 0)
  239. $("body").append('<div id="facebox_overlay" class="facebox_hide"></div>')
  240. $('#facebox_overlay').hide().addClass("facebox_overlayBG")
  241. .css('opacity', $.facebox.settings.opacity)
  242. .click(function() { $(document).trigger('close.facebox') })
  243. .fadeIn(200)
  244. return false
  245. }
  246. function hideOverlay() {
  247. if (skipOverlay()) return
  248. $('#facebox_overlay').fadeOut(200, function(){
  249. $("#facebox_overlay").removeClass("facebox_overlayBG")
  250. $("#facebox_overlay").addClass("facebox_hide")
  251. $("#facebox_overlay").remove()
  252. })
  253. return false
  254. }
  255. /*
  256. * Bindings
  257. */
  258. $(document).bind('close.facebox', function() {
  259. $(document).unbind('keydown.facebox')
  260. $('#facebox').fadeOut(function() {
  261. $('#facebox .content').removeClass().addClass('content')
  262. $('#facebox .loading').remove()
  263. $(document).trigger('afterClose.facebox')
  264. })
  265. hideOverlay()
  266. })
  267. })(jQuery);