PageSourceSearch

https://www.gordonramsayrestaurants.com/mysite/js/jquery.zebra.accordion.js

js gordonramsayrestaurants.com collected 2026-10-01 11:28:06 UTC 20,160 bytes, 558 lines download raw bytes

1/**
2 *  Zebra_Accordion
3 *
4 *  A tiny (3KB minified) accordion plugin for jQuery.
5 *
6 *  It transforms a basic definition list, without requiring any other specific markup, into a small-footprint, easily
7 *  configurable, fully customizable, cross-browser accordion widget, useful for better organizing larger groups of content.
8 *
9 *  Features:
10 *
11 *  -   no additional markup required other than a basic definition list;
12 *  -   easily customizable through CSS;
13 *  -   works with both fixed and fluid (responsive) layouts;
14 *  -   can be configured to work so that only a single can be expanded at a time, or so that all tabs may be
15 *      expanded/collapsed;
16 *  -   can be configured to work so tabs expand on mouse over;
17 *  -   when, after expanding a tab, part of its content is outside the viewport, it automatically scrolls the browser's
18 *      window so that the tab's content is visible;
19 *  -   callback functions can be used for further customizations;
20 *  -   works in all major browsers (Firefox, Opera, Safari, Chrome, Internet Explorer 6, 7, 8, 9)
21 *
22 *  Visit {@link http://stefangabos.ro/jquery/zebra-accordion/} for more information.
23 *
24 *  For more resources visit {@link http://stefangabos.ro/}
25 *
26 *  @author     Stefan Gabos <[email protected]>
27 *  @version    1.2.2 (last revision: November 28, 2013)
28 *  @copyright  (c) 2011 - 2013 Stefan Gabos
29 *  @license    http://www.gnu.org/licenses/lgpl-3.0.txt GNU LESSER GENERAL PUBLIC LICENSE
30 *  @package    Zebra_Accordion
31 */
32;(function($) {
33
34	$.Zebra_Accordion = function(el, options) {
35
36		var defaults = {
37
38			animate_opacity:        true,                       //  Should the content block's opacity be also animated?
39																//
40																//  Default is TRUE
41
42			collapsible:            false,                      //  If set to TRUE, an open block can also be c
42ollapsed
43																//  - in this case, all blocks can be collapsed; if set
44																//  to FALSE, an open block can be collapsed only by
45																//  opening another block - in this case, only a single
46																//  block is open at any given moment;
47																//
48																//  Default is FALSE
49
50			expanded_class:         'Zebra_Accordion_Expanded', //  The name of the class to append to the "title"
51																//  element when its associated content block is
52																//  expanded.
53																//
54																//  Can be used for customizing the aspect of the opened
55																//  tab to give better visual feedback to the users.
56																//
57																//  Default is "Zebra_Accordion_Expanded"
58
59			hide_speed:             400,                        //  The speed (in milliseconds) to use when collapsing
60																//  content blocks.
61																//
62																//  Default is 400
63
64			scroll_speed:           600,                        //  If a content block's content is not entirely visible
65																//  after it is expanded, the window will be scrolled so
66																//  so that the entire content of the content block is
67																//  visible (if it is possible).
68																//
69																//  This value represents the speed (in milliseconds) to
70																//  use for scrolling.
71																//
72																//  Default is 600
73
74			show_speed:             400,                        //  The speed (in milliseconds) to use when expanding
75																//  content blocks.
76																//
77																//  Default is 400
78
79			show:                   0,                          //  The index (0 based) of the content block to be
80																//  expanded by default.
81																//
82																//  The value of this property can also be boolean FALSE,
83																//  indicating that all tabs should be collapsed by default.
84																//
85																//  If the value of the "collapsible" property is TRUE,
86																//  the value of this property can also be boolean TRUE,
87																//  indicating that all tabs should be expanded by default,
88																//  or an array with the indexes of tabs to be expanded
89																//  by default.
90																//
91																//  Default is 0
92
93			toggle_on_mouseover:    false,                      //  Set this to TRUE if content blocks should be expanded
94																//  when hovering their associated "titles".
95																//
96																//  If "collapsible" is TRUE then this property will
97																//  always be FALSE!
98																//
99																//  Default is FALSE;
100
101			onBeforeClose:          null,                       //  Event fired before a content block is collapsed.
102																//
103																//  The callback function (if any) receives as arguments
104																//  the closed item's number (0 based), the title element
105																//  and the content block element.
106																//
107			onBeforeOpen:           null,                       //  Event fired before a content block is expanded.
108																//
109																//  The callback function (if any) receives as arguments
110																//  the closed item's number (0 based), the title element
111																//  and the content block element.
112
113			onClose:                null,                       //  Event fired after a content block is collapsed.
114																//
115																//  The callback function (if any) receives as arguments
116																//  the closed item's number (0 based), the title element
117																//  and the content block element.
118
119			onOpen:                 null                        //  Event fired after a content block is expanded.
120																//
121																//  The callback function (if any) receives as arguments
122																//  the opened item's number (0 based), the title element
123																//  and the content block element.
124
125		};
126
127		var
128
129			// to avoid confusions, we use "plugin" to reference the current instance of the plugin
130			plugin = this,
131
132			// private lookup arrays
133			$titles = null,
134			$blocks = null,
135
136			titles = [],
137			blocks = [];
138
139		plugin.settings = {};
140
141		/**
142		 *  Constructor method
143		 *
144		 *  @return object  Returns a reference to the plugin
145		 */
146		var init = function() {
147
148			// the plugin's final properties are the merged default and user-prov
148ided options (if any)
149			plugin.settings = $.extend({}, defaults, options);
150
151			var $element =  $(el);  // reference to the jQuery version of DOM element the plugin is attached to
152
153			$titles = $('dt', $element);    // references to the title elements
154			$blocks = $('dd', $element);    // references to the content blocks
155
156			// iterate through the title elements and get some information about each element
157			_get_titles_info();
158
159			// iterate through the content block elements and get some information about each element
160			_get_blocks_info();
161
162			// if a content block is to be shown by default
163			if (plugin.settings.show !== false) {
164
165				// if any number of content blocks can be expanded/collapsed, and by default we have to expand a certain
166				// set of content blocks, or all
167				if (plugin.settings.collapsible && ($.isArray(plugin.settings.show) || plugin.settings.show === true)) {
168
169					// if we have to expand all content blocks
170					if (plugin.settings.show === true)
171
172						// expand all content blocks
173						for (var i = 0; i < $titles.length; i++) plugin.show(i, true, true);
174
175					// if we only have to expand certain content blocks
176					else
177
178						// iterate through the content blocks that need to be expanded
179						$.each(plugin.settings.show, function(index) {
180
181							// expand each content block
182							plugin.show(plugin.settings.show[index], true, true);
183
184						});
185
186				// otherwise, show the default content block
187				} else plugin.show(plugin.settings.show, true, true);
188
189			}
190
191			// run a function whenever the browser's window is resized
192			$(window).bind('resize', function() {
193
194				// by default, we assume that there's no tab opened
195				var open = [];
196
197				// iterate through the title elements
198				$titles.each(function(index) {
199
200					// reference to the title element
201					var $title = $(this);
202
203					// if we find an opened tab, save the tab's number for later
204					if ($title.hasClass(plugin.settings.expanded_class)) open.push(index);
205
206					// set the title element's "style" attribute back to its original state (before running the plugin)
207					$title.attr('style', titles[index].style);
208
209				});
210
211				// iterate through the title elements and get some information about each element
212				// also, make sure we don't re-bind callback functions to events
213				_get_titles_info(false);
214
215				// iterate through the content block elements
216				$blocks.each(function(index) {
217
218					// set the content element's "style" attribute back to its original state (before running the plugin)
219					$(this).attr('style', blocks[index].style);
220
221				});
222
223				// iterate through the content elements and get some information about each element
224				_get_blocks_info();
225
226				// if there were open tabs
227				if (open.length > 0)
228
229					// re-open them now
230					$.each(open, function(index) {
231
232						plugin.show(open[index], true, true);
233
234					});
235
236			});
237
238		};
239
240		/**
241		 *  Expands a content block.
242		 *
243		 *  @param  integer index       The 0-based index of the content block to expand.
244		 *
245		 *  @param  boolean noFx        (Optional) If set to TRUE, the content block will be instantly expanded without
246		 *                              animation.
247		 *
248		 *                              Default is FALSE.
249		 *
250		 *  @param  boolean noScroll    (Optional) If set to TRUE, the browser window will not be scrolled to the newly
251		 *                              expanded content block.
252		 *
253		 *                              Default is FALSE.
254		 *  @return void
255		 */
256		plugin.show = function(index, noFx, noScroll) {
257
258			// if "index" is an integer, greater than 0 and lesser than the total number of items
259			if (null !== new String(index).match(/^[0-9]+$/) && index >= 0 && index <= blocks.length - 1) {
260
261				var $title = $($titles[index]), // reference to the title element
262					$block = $($blocks[index]), // reference to the content block element
263					block = blocks[index];      // get the block's properties
264
265				// if a callback function needs to be called before expanding the content block
266				if (plugin.settings.onBeforeOpen && typeof plugin.settings.onBeforeOpen == 'function')
267
268					// execute the callback function
269					plugin.settings.onBeforeOpen(index, $title, $block);
270
271				// if any block can can be expanded/collapsed at any time
272				// and current block is already expanded, collapse it instead
273				if (plugin.settings.collapsible && $block.height() > 0) return plugin.hide(index, noFx);
274
275				// if only a single block can be expanded at a time
276				else if (!plugin.settings.collapsible)
277
278					// iterate through the content blocks
279					$blocks.each(function(key) {
280
281						// if not the block that we are about to expand
282						// collapse the content block
283						if (key != index) plugin.hide(key, noFx);
284
285					});
286
287				// add an extra class to the title element, to indicate that the element is expanded
288				// useful for custom styling of the title element, to give a better visual feedback to the users
289				$title.addClass(plugin.settings.expanded_class);
290
291				// set the content block's "display" property to "block"
292				$block.css('display', 'block');
293
294				// stop any ongoing animation on the current content block
295				$block.stop();
296
297				// expand the indicated content block
298				$block.animate({
299
300					'height':               block.height,
301					'paddingTop':           block.paddingTop,
302					'paddingBottom':        block.paddingBottom,
303					'marginTop':            block.marginTop,
304					'marginBottom':         block.marginBottom,
305					'opacity':              1
306
307				// using the speed as indicated in the settings
308				}, (noFx ? 0 : plugin.settings.show_speed),
309
310				// once the animation is complete
311				function() {
312
313					// if a callback function needs to be called after opening the content block
314					if (plugin.settings.onOpen && typeof plugin.settings.onOpen == 'function')
315
316						// execute the callback function
317						plugin.settings.onOpen(index, $title, $block);
318
319					// if scrolling is not explicitly disabled
320					if (!noScroll) {
321
322						var title_top = Math.round($title.offset().top),                //  the title's "top" position
323							title_height = titles[index].height,                        //  the title's height
324							block_height = block.outerHeight,                           //  the content block's height
325							total_height = title_top + title_height + block_height,     //  item's total height
326							viewport_height = $(window).height(),                       //  visible area in the browser
327							viewport_scroll = $(window).scrollTop(),                    //  how much is the page scrolled down (from the top)
328							offset = null;
329
330						// if a content block's bottom goes out of the view
331						if (total_height > viewport_height + viewport_scroll) {
332
333							// this is how much the page needs to be scrolled down (from the top) so that the content is visible
334							offset = total_height - viewport_height;
335
336							// but, if that would mean that the title would end up above the visible area
337							// better to scroll to the title instead
338							if (offset > title_top) offset = title_top;
339
340						}
341
342						// if title is above the visible area, scroll back up, so that the title becomes visible
343						if (title_top < viewport_scroll) offset = title_top;
344
345						// if we need to scroll the content
346						if (offset)
347
348							// smoothly scroll the page
349							$('html, body').animate({
350
351								scrollTop: offset
352
353							// using the speed as indicated in the settings
354							}, plugin.settings.scroll_speed);
355
356					}
357
358				});
359
360			}
361
362		};
363
364		/**
365		 *  Collapses a content block.
366		 *
367		 *  @param  integer index   The 0-based index of the content block to collapse.
368		 *
369		 *  @param  boolean noFx    (Optional) If set to TRUE, the content block will be instantly collapsed without
370		 *                          animation.
371		 *
372		 *                          Default is FALSE.
373		 *
374		 *  @return void
375		 */
376		plugin.hide = function(index, noFx) {
377
378			// if "index" is an integer, greater than 0 and lesser than the total number of items, and the respective block is not already collapsed
379			if (null !== new String(index).match(/^[0-9]+$/) && index >= 0 && index <= blocks.length - 1) {
380
381				var $title = $($titles[index]), //  reference to the title element
382					$block = $($blocks[index]), //  reference to the content block element
383					block = blocks[index];      //  get the block's properties
384
385				// if a callback function needs to be called before collapsing the content block
386				if (plugin.settings.onBeforeClose && typeof plugin.settings.onBeforeClose == 'function')
387
388					// execute the callback function
389					plugin.settings.onBeforeClose(index, $title, $block);
390
391				// remove the extra class added to the title element when the associated block was expanded
392				$title.removeClass(plugin.settings.expanded_class);
393
394				// stop any ongoing animation for the current content block
395				$block.stop();
396
397				// supress top and bottom borders
398				$block.css({
399					'borderTopWidth':       0,
400					'borderBottomWidth':    0
401				});
402
403				// hide the element
404				$block.animate({
405
406					'height':           0,
407					'paddingTop':       0,
408					'paddingBottom':    0,
409					'marginTop':        0,
410					'marginBottom':     0,
411					'opacity':          (plugin.settings.animate_opacity ? 0 : 1)
412
413				// using the speed as indicated in the settings
414				}, (noFx ? 0 : plugin.settings.hide_speed),
415
416				// once the animation is complete
417				function() {
418
419					// if a callback function needs to be called after closing the content block
420					if (plugin.settings.onClose && typeof plugin.settings.onClose == 'function')
421
422						// execute the callback function
423						plugin.settings.onClose(index, $title, $block);
424
425					// set some of content block element's CSS properties
426					$(this).css({
427						'display':              'none',
428						'visibility':           'visible',
429						'borderTopWidth':       block.borderTopWidth,
430						'borderBottomWidth':    block.borderBottomWidth
431					});
432
433				});
434
435			}
436
437		};
438
439		/**
440		 *  Gets some CSS properties for the accordion's content blocks
441		 *
442		 *  @return void
443		 *
444		 *  @access private
445		 */
446		var _get_blocks_info = function() {
447
448			// reset the lookup array
449			blocks = [];
450
451			// iterate through the content blocks
452			$blocks.each(function(index) {
453
454				// reference to the content block jQuery object
455				var $block = $(this);
456
457				// temporary make set content block's "display" property to "block",
458				// in order to be able to get some of the element's CSS properties
459				$block.css({
460					'visibility':   'hidden',
461					'display':      'block'
462				});
463
464				// get some of the element's CSS properties
465				// needed to correctly expand/collapse the block
466				// and add them to our lookup array
467				blocks.push({
468					'height':               $block.height(),
469					'outerHeight':          $block.outerHeight(),
470					'paddingTop':           _int($block.css('paddingTop')),
471					'paddingBottom':        _int($block.css('paddingBottom')),
472					'marginTop':            _int($block.css('marginTop')),
473					'marginBottom':         _int($block.css('marginBottom')),
474					'borderTopWidth':       _int($block.css('borderTopWidth')),
475					'borderBottomWidth':    _int($block.css('borderBottomWidth')),
476					'style':                $block.attr('style')                    // element's original style (if any)
477				});
478
479				// all blocks are collapsed by default
480				plugin.hide(index, true);
481
482			});
483
484		};
485
486		/**
487		 *  Gets some CSS properties for the accordion's title blocks
488		 *
489		 *  @return void
490		 *
491		 *  @access private
492		 */
493		var _get_titles_info = function(nobind) {
494
495			// reset the lookup array
496			titles = [];
497
498			// iterate through the content titles
499			$titles.each(function(index) {
500
501				var
502
503					// reference to the element
504					$title = $(this),
505
506					// the event that should trigger content blocks expansion/collapse
507					event = !plugin.settings.collapsible && plugin.settings.toggle_on_mouseover ?
508								'mouseover' :
509								'click';
510
511				// get some of the element's CSS properties
512				// needed to correctly expand/collapse the block
513				// and add them to our lookup array
514				titles.push({
515					'height':   $title.outerHeight(),   // the title's height, including margins and padding
516					'style':    $title.attr('style')    // the element's original style attribute (if any)
517				});
518
519				// if we need to handle the required event
520				// (this method may also be called internally upon resizing of the browser window
521				// case in which we don't need to re-attach the function to the required event)
522				if (undefined === nobind)
523
524					// handle the required event (click or mouseover - see above)
525					$title.bind(event, function() {
526
527						// show the associated content block
528						plugin.show(index);
529
530					});
531
532			});
533
534		};
535
536		/**
537		 *  A wrapper to JavaScript's parseInt() function.
538		 *
539		 *  @return int     Returns the integer representation of the string given as argument
540		 *
541		 *  @access private
542		 */
543		var _int = function(value) {
544
545			// convert value to an integer
546			value = parseInt(value, 10);
547
548			// if result is not a number (NaN) return 0, or the converted value otherwise
549			return isNaN(value) ? 0 : value;
550
551		};
552
553		// fire it up!
554		init();
555
556	};
557
558})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.