countdown.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /*
  2. * jQuery The Final Countdown plugin v1.0.0 beta
  3. * http://github.com/hilios/jquery.countdown
  4. *
  5. * Copyright (c) 2011 Edson Hilios
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining
  8. * a copy of this software and associated documentation files (the
  9. * "Software"), to deal in the Software without restriction, including
  10. * without limitation the rights to use, copy, modify, merge, publish,
  11. * distribute, sublicense, and/or sell copies of the Software, and to
  12. * permit persons to whom the Software is furnished to do so, subject to
  13. * the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be
  16. * included in all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  21. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  22. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  23. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  24. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. */
  26. (function($) {
  27. $.fn.countdown = function(toDate, callback) {
  28. var handlers = ['seconds', 'minutes', 'hours', 'days', 'weeks', 'daysLeft'];
  29. function delegate(scope, method) {
  30. return function() { return method.call(scope) }
  31. }
  32. return this.each(function() {
  33. // Convert
  34. if(!(toDate instanceof Date)) {
  35. if(String(toDate).match(/^[0-9]*$/)) {
  36. toDate = new Date(toDate);
  37. } else if( toDate.match(/([0-9]{1,2})\/([0-9]{1,2})\/([0-9]{2,4})\s([0-9]{1,2})\:([0-9]{2})\:([0-9]{2})/) ||
  38. toDate.match(/([0-9]{2,4})\/([0-9]{1,2})\/([0-9]{1,2})\s([0-9]{1,2})\:([0-9]{2})\:([0-9]{2})/)
  39. ) {
  40. toDate = new Date(toDate);
  41. } else if(toDate.match(/([0-9]{1,2})\/([0-9]{1,2})\/([0-9]{2,4})/) ||
  42. toDate.match(/([0-9]{2,4})\/([0-9]{1,2})\/([0-9]{1,2})/)
  43. ) {
  44. toDate = new Date(toDate)
  45. } else {
  46. throw new Error("Doesn't seen to be a valid date object or string")
  47. }
  48. }
  49. var $this = $(this),
  50. values = {},
  51. lasting = {},
  52. interval = $this.data('countdownInterval'),
  53. currentDate = new Date(),
  54. secondsLeft = Math.floor((toDate.valueOf() - currentDate.valueOf()) / 1000);
  55. function triggerEvents() {
  56. secondsLeft--;
  57. if(secondsLeft < 0) {
  58. secondsLeft = 0;
  59. }
  60. lasting = {
  61. seconds : secondsLeft % 60,
  62. minutes : Math.floor(secondsLeft / 60) % 60,
  63. hours : Math.floor(secondsLeft / 60 / 60) % 24,
  64. days : Math.floor(secondsLeft / 60 / 60 / 24),
  65. weeks : Math.floor(secondsLeft / 60 / 60 / 24 / 7),
  66. daysLeft: Math.floor(secondsLeft / 60 / 60 / 24) % 7
  67. }
  68. for(var i=0; i<handlers.length; i++) {
  69. var eventName = handlers[i];
  70. if(values[eventName] != lasting[eventName]) {
  71. values[eventName] = lasting[eventName];
  72. dispatchEvent(eventName);
  73. }
  74. }
  75. if(secondsLeft == 0) {
  76. stop();
  77. dispatchEvent('finished');
  78. }
  79. }
  80. triggerEvents();
  81. function dispatchEvent(eventName) {
  82. var event = $.Event(eventName);
  83. event.date = new Date(new Date().valueOf() + secondsLeft);
  84. event.value = values[eventName] || "0";
  85. event.toDate = toDate;
  86. event.lasting = lasting;
  87. switch(eventName) {
  88. case "seconds":
  89. case "minutes":
  90. case "hours":
  91. event.value = event.value < 10 ? '0'+event.value.toString() : event.value.toString();
  92. break;
  93. default:
  94. if(event.value) {
  95. event.value = event.value.toString();
  96. }
  97. break;
  98. }
  99. callback.call($this, event);
  100. }
  101. $this.bind('remove', function() {
  102. stop(); // If the selector is removed clear the interval for memory sake!
  103. dispatchEvent('removed');
  104. });
  105. function stop() {
  106. clearInterval(interval);
  107. }
  108. function start() {
  109. $this.data('countdownInterval', setInterval(delegate($this, triggerEvents), 1000));
  110. interval = $this.data('countdownInterval');
  111. }
  112. if(interval) stop();
  113. start();
  114. });
  115. }
  116. // Wrap the remove method to trigger an event when called
  117. var removeEvent = new $.Event('remove'),
  118. removeFunction = $.fn.remove;
  119. $.fn.remove = function() {
  120. $(this).trigger(removeEvent);
  121. removeFunction.apply(this, arguments);
  122. }
  123. })(jQuery);
  124. /*
  125. * $ lightbox_me
  126. * By: Buck Wilson
  127. * Version : 2.3
  128. *
  129. * Licensed under the Apache License, Version 2.0 (the "License");
  130. * you may not use this file except in compliance with the License.
  131. * You may obtain a copy of the License at
  132. *
  133. * http://www.apache.org/licenses/LICENSE-2.0
  134. *
  135. * Unless required by applicable law or agreed to in writing, software
  136. * distributed under the License is distributed on an "AS IS" BASIS,
  137. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  138. * See the License for the specific language governing permissions and
  139. * limitations under the License.
  140. */
  141. (function($) {
  142. $.fn.lightbox_me = function(options) {
  143. return this.each(function() {
  144. var
  145. opts = $.extend({}, $.fn.lightbox_me.defaults, options),
  146. $overlay = $(),
  147. $self = $(this),
  148. $iframe = $('<iframe id="foo" style="z-index: ' + (opts.zIndex + 1) + ';border: none; margin: 0; padding: 0; position: absolute; width: 100%; height: 100%; top: 0; left: 0; filter: mask();"/>'),
  149. ie6 = ($.browser.msie && $.browser.version < 7);
  150. if (opts.showOverlay) {
  151. //check if there's an existing overlay, if so, make subequent ones clear
  152. var $currentOverlays = $(".js_lb_overlay:visible");
  153. if ($currentOverlays.length > 0){
  154. $overlay = $('<div class="lb_overlay_clear js_lb_overlay"/>');
  155. } else {
  156. $overlay = $('<div class="' + opts.classPrefix + '_overlay js_lb_overlay"/>');
  157. }
  158. }
  159. /*----------------------------------------------------
  160. DOM Building
  161. ---------------------------------------------------- */
  162. if (ie6) {
  163. var src = /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank';
  164. $iframe.attr('src', src);
  165. $('body').append($iframe);
  166. } // iframe shim for ie6, to hide select elements
  167. $('body').append($self.hide()).append($overlay);
  168. /*----------------------------------------------------
  169. Overlay CSS stuffs
  170. ---------------------------------------------------- */
  171. // set css of the overlay
  172. if (opts.showOverlay) {
  173. setOverlayHeight(); // pulled this into a function because it is called on window resize.
  174. $overlay.css({ position: 'absolute', width: '100%', top: 0, left: 0, right: 0, bottom: 0, zIndex: (opts.zIndex + 2), display: 'none' });
  175. if (!$overlay.hasClass('lb_overlay_clear')){
  176. $overlay.css(opts.overlayCSS);
  177. }
  178. }
  179. /*----------------------------------------------------
  180. Animate it in.
  181. ---------------------------------------------------- */
  182. //
  183. if (opts.showOverlay) {
  184. $overlay.fadeIn(opts.overlaySpeed, function() {
  185. setSelfPosition();
  186. $self[opts.appearEffect](opts.lightboxSpeed, function() { setOverlayHeight(); setSelfPosition(); opts.onLoad()});
  187. });
  188. } else {
  189. setSelfPosition();
  190. $self[opts.appearEffect](opts.lightboxSpeed, function() { opts.onLoad()});
  191. }
  192. /*----------------------------------------------------
  193. Hide parent if parent specified (parentLightbox should be jquery reference to any parent lightbox)
  194. ---------------------------------------------------- */
  195. if (opts.parentLightbox) {
  196. opts.parentLightbox.fadeOut(200);
  197. }
  198. /*----------------------------------------------------
  199. Bind Events
  200. ---------------------------------------------------- */
  201. $(window).resize(setOverlayHeight)
  202. .resize(setSelfPosition)
  203. .scroll(setSelfPosition);
  204. $(window).bind('keyup.lightbox_me', observeKeyPress);
  205. if (opts.closeClick) {
  206. $overlay.click(function(e) { closeLightbox(); e.preventDefault; });
  207. }
  208. $self.delegate(opts.closeSelector, "click", function(e) {
  209. closeLightbox(); e.preventDefault();
  210. });
  211. $self.bind('close', closeLightbox);
  212. $self.bind('reposition', setSelfPosition);
  213. /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  214. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
  215. /*----------------------------------------------------
  216. Private Functions
  217. ---------------------------------------------------- */
  218. /* Remove or hide all elements */
  219. function closeLightbox() {
  220. var s = $self[0].style;
  221. if (opts.destroyOnClose) {
  222. $self.add($overlay).remove();
  223. } else {
  224. $self.add($overlay).hide();
  225. }
  226. //show the hidden parent lightbox
  227. if (opts.parentLightbox) {
  228. opts.parentLightbox.fadeIn(200);
  229. }
  230. $iframe.remove();
  231. // clean up events.
  232. $self.undelegate(opts.closeSelector, "click");
  233. $(window).unbind('reposition', setOverlayHeight);
  234. $(window).unbind('reposition', setSelfPosition);
  235. $(window).unbind('scroll', setSelfPosition);
  236. $(window).unbind('keyup.lightbox_me');
  237. if (ie6)
  238. s.removeExpression('top');
  239. opts.onClose();
  240. }
  241. /* Function to bind to the window to observe the escape/enter key press */
  242. function observeKeyPress(e) {
  243. if((e.keyCode == 27 || (e.DOM_VK_ESCAPE == 27 && e.which==0)) && opts.closeEsc) closeLightbox();
  244. }
  245. /* Set the height of the overlay
  246. : if the document height is taller than the window, then set the overlay height to the document height.
  247. : otherwise, just set overlay height: 100%
  248. */
  249. function setOverlayHeight() {
  250. if ($(window).height() < $(document).height()) {
  251. $overlay.css({height: $(document).height() + 'px'});
  252. $iframe.css({height: $(document).height() + 'px'});
  253. } else {
  254. $overlay.css({height: '100%'});
  255. if (ie6) {
  256. $('html,body').css('height','100%');
  257. $iframe.css('height', '100%');
  258. } // ie6 hack for height: 100%; TODO: handle this in IE7
  259. }
  260. }
  261. /* Set the position of the modal'd window ($self)
  262. : if $self is taller than the window, then make it absolutely positioned
  263. : otherwise fixed
  264. */
  265. function setSelfPosition() {
  266. var s = $self[0].style;
  267. // reset CSS so width is re-calculated for margin-left CSS
  268. $self.css({left: '50%', marginLeft: ($self.outerWidth() / 2) * -1, zIndex: (opts.zIndex + 3) });
  269. /* we have to get a little fancy when dealing with height, because lightbox_me
  270. is just so fancy.
  271. */
  272. // if the height of $self is bigger than the window and self isn't already position absolute
  273. if (($self.height() + 80 >= $(window).height()) && ($self.css('position') != 'absolute' || ie6)) {
  274. // we are going to make it positioned where the user can see it, but they can still scroll
  275. // so the top offset is based on the user's scroll position.
  276. var topOffset = $(document).scrollTop() + 40;
  277. $self.css({position: 'absolute', top: topOffset + 'px', marginTop: 0})
  278. if (ie6) {
  279. s.removeExpression('top');
  280. }
  281. } else if ($self.height()+ 80 < $(window).height()) {
  282. //if the height is less than the window height, then we're gonna make this thing position: fixed.
  283. // in ie6 we're gonna fake it.
  284. if (ie6) {
  285. s.position = 'absolute';
  286. if (opts.centered) {
  287. s.setExpression('top', '(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"')
  288. s.marginTop = 0;
  289. } else {
  290. var top = (opts.modalCSS && opts.modalCSS.top) ? parseInt(opts.modalCSS.top) : 0;
  291. s.setExpression('top', '((blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"')
  292. }
  293. } else {
  294. if (opts.centered) {
  295. $self.css({ position: 'fixed', top: '50%', marginTop: ($self.outerHeight() / 2) * -1})
  296. } else {
  297. $self.css({ position: 'fixed'}).css(opts.modalCSS);
  298. }
  299. }
  300. }
  301. }
  302. });
  303. };
  304. $.fn.lightbox_me.defaults = {
  305. // animation
  306. appearEffect: "fadeIn",
  307. appearEase: "",
  308. overlaySpeed: 250,
  309. lightboxSpeed: 300,
  310. // close
  311. closeSelector: ".close",
  312. closeClick: true,
  313. closeEsc: true,
  314. // behavior
  315. destroyOnClose: false,
  316. showOverlay: true,
  317. parentLightbox: false,
  318. // callbacks
  319. onLoad: function() {},
  320. onClose: function() {},
  321. // style
  322. classPrefix: 'lb',
  323. zIndex: 999,
  324. centered: false,
  325. modalCSS: {top: '40px'},
  326. overlayCSS: {background: 'black', opacity: .3}
  327. }
  328. })(jQuery);