PageSourceSearch

https://psk68.ru/plugins/content/pb_spoiler/accordion.js

js psk68.ru collected 2026-10-07 07:44:02 UTC 8,518 bytes, 272 lines download raw bytes

1/*
2 * Accordion 1.3 - jQuery menu widget
3 *
4 * Copyright (c) 2006 Jörn Zaefferer, Frank Marcia
5 *
6 * Dual licensed under the MIT and GPL licenses:
7 *   http://www.opensource.org/licenses/mit-license.php
8 *   http://www.gnu.org/licenses/gpl.html
9 *
10 * Revision: $Id: jquery.accordion.js 1524 2007-03-13 20:09:19Z joern $
11 *
12 */
13
14/**
15 * Make the selected elements Accordion widgets.
16 *
17 * Semantic requirements:
18 *
19 * If the structure of your container is flat with unique
20 * tags for header and content elements, eg. a definition list
21 * (dl > dt + dd), you don't have to specify any options at
22 * all.
23 *
24 * If your structure uses the same elements for header and
25 * content or uses some kind of nested structure, you have to
26 * specify the header elements, eg. via class, see the second example.
27 *
28 * Use activate(Number) to change the active content programmatically.
29 *
30 * A change event is triggered everytime the accordion changes. Apart from
31 * the event object, all arguments are jQuery objects.
32 * Arguments: event, newHeader, oldHeader, newContent, oldContent
33 *
34 * @example jQuery('#nav').Accordion();
35 * @before <dl id="nav">
36 *   <dt>Header 1</dt>
37 *   <dd>Content 1</dd>
38 *   <dt>Header 2</dt>
39 *   <dd>Content 2</dd>
40 * </dl>
41 * @desc Creates an Accordion from the given definition list
42 *
43 * @example jQuery('#nav').Accordion({
44 *   header: 'div.title'
45 * });
46 * @before <div id="nav">
47 *  <div>
48 *    <div class="title">Header 1</div>
49 *    <div>Content 1</div>
50 *  </div>
51 *  <div>
52 *    <div class="title">Header 2</div>
53 *    <div>Content 2</div>
54 *  </div>
55 * </div>
56 * @desc Creates an Accordion from the given div structure
57 *
58 * @example jQuery('#nav').Accordion({
59 *   header: 'a.head'
60 * });
61 * @before <ul id="nav">
62 *   <li>
63 *     <a class="head">Header 1</a>
64 *     <ul>
65 *       <li><a href="#">Link 1</a></li>
66 *       <li><a href="#">Link 2></a></li>
67 *     </ul>
68 *   </li>
69 *   <li>
70 *     <a class="head">Header 2</a>
71 *     <ul>
72 *       <li><a href="#">Link 3</a></li>
73 *       <li><a href="#">Link 4></a></li>
74 *     </ul>
75 *   </li>
76 * </ul>
77 * @desc Creates an Accordion from the given navigation list
78 *
79 * @example jQuery('#accordion').Accordion().change(function(event, newHeader, oldHeader, newContent, oldContent) {
80 *   jQuery('#status').html(newHeader.text());
81 * });
82 * @desc Updates the element with id status with the text of the selected header every time the accordion changes
83 *
84 * @param Map options key/value pairs of optional settings.
85 * @option String|Element|jQuery|Boolean active Selector for the active element, default is the first child, set to false to display none at start
86 * @option String|Element|jQuery header Selector for the header element, eg. div.title, a.head, default is the first child's tagname
87 * @option String|Number showSpeed Speed for the slideIn, default is 'slow' (for numbers: smaller = faster)
88 * @option String|Number hideSpeed Speed for the slideOut, default is 'fast' (for numbers: smaller = faster)
89 * @option String selectedClass Class for active header elements, default is 'selected'
90 * @option Boolean alwaysOpen Whether there must be one content element open, default is true.
91 * @option Boolean animated Set to false to disable animations. Default: true
92 * @option String event The event on which to trigger the accordion, eg. "mouseover". Default: "click"
93 *
94 * @type jQuery
95 * @see activate(Number)
96 * @name Accordion
97 * @cat Plugins/Accordion
98 */
99
100/**
101 * Activate a content part of the Accordion programmatically at the given zero-based index.
102 *
103 * If the index is not specified, it defaults to zero, if it is an invalid index, eg. a string,
104 * nothing happens.
105 *
106 * @example jQuery('#accordion').activate(1);
107 * @desc Activate the second content of the Accordion contained in <div id="accordion">.
108 *
109 * @example jQuery('#nav').activate();
110 * @desc Activate the first content of the Accordion contained in <ul id="nav">.
111 *
112 * @param Number index (optional) An Integer specifying the zero-based index of the content to be
113 *				 activated. Default: 0
114 *
115 * @type jQuery
116 * @name activate
117 * @cat Plugins/Accordion
118 */
119 
120/**
121 * Override the default settings of the Accordion. Affects only following plugin calls.
122 *
123 * @example jQuery.Accordion.setDefaults({
124 * 	showSpeed: 1000,
125 * 	hideSpeed: 150
126 * });
127 *
128 * @param Map options key/value pairs of optional settings, see Accordion() for details
129 *
130 * @type jQuery
131 * @name setDefaults
132 * @cat Plugins/Accordion
133 */
134
135jQuery.fn.extend({
136	// nextUntil is necessary, would be nice to have this in jQuery core
137	nextUntil: function(expr) {
138	    var match = [];
139	
140	    // We need to figure out which elements to push onto the array
141	    this.each(function(){
142	        // Traverse through the sibling nodes
143	        for( var i = this.nextSibling; i; i = i.nextSibling ) {
144	            // Make sure that we're only dealing with elements
145	            if ( i.nodeType != 1 ) continue;
146	
147	            // If we find a match then we need to stop
148	            if (jQuery.filter(expr, [i]).length) break;
149	
150	            // Otherwise, add it on to the stack
151	            match.push( i );
152	        }
153	    });
154	
155	    return this.pushStack( match );
156	},
157	// the plugin method itself
158	Accordion: function(settings) {
159		// setup configuration
160		settings = jQuery.extend({}, jQuery.Accordion.defaults, {
161			// define context defaults
162			header: jQuery(':first-child', this)[0].tagName // take first childs tagName as header
163		}, settings);
164
165		// calculate active if not specified, using the first header
166		var container = this,
167			active = settings.active
168				? jQuery(settings.active, this)
169				: settings.active === false
170					? jQuery("<div>")
171					: jQuery(settings.header, this).eq(0),
172			running = 0;
173
174		container.find(settings.header)
175			.not(active || "")
176			.nextUntil(settings.header)
177			.hide();
178		active.addClass(settings.selectedClass);
179
180		function clickHandler(event) {
181			// get the click target
182			var clicked = jQuery(event.target);
183			
184			// due to the event delegation model, we have to check if one
185			// of the parent elements is our actual header, and find that
186			if ( clicked.parents(settings.header).length ) {
187				while ( !clicked.is(settings.header) ) {
188					clicked = clicked.parent();
189				}
190			}
191			
192			var clickedActive = clicked[0] == active[0];
193			
194			// if animations are still active, or the active header is the target, ignore click
195			if(running || (settings.alwaysOpen && clickedActive) || !clicked.is(settings.header))
196				return;
197
198			// switch classes
199			active.toggleClass(settings.selectedClass);
200			if ( !clickedActive ) {
201				clicked.addClass(settings.selectedClass);
202			}
203
204			// find elements to show and hide
205			var toShow = clicked.nextUntil(settings.header),
206				toHide = active.nextUntil(settings.header),
207				data = [clicked, active, toShow, toHide];
208			active = clickedActive ? jQuery([]) : clicked;
209			// count elements to animate
210			running = toHide.size() + toShow.size();
211			var finished = function(cancel) {
212				running = cancel ? 0 : --running;
213				if ( running )
214					return;
215
216				// trigger custom change event
217				container.trigger("change", data);
218			};
219			// TODO if hideSpeed is set to zero, animations are crappy
220			// workaround: use hide instead
221			// solution: animate should check for speed of 0 and do something about it
222			if ( settings.animated ) {
223				if ( !settings.alwaysOpen && clickedActive ) {
224					toShow.slideToggle(settings.showSpeed);
225					finished(true);
226				} else {
227					toHide.filter(":hidden").each(finished).end().filter(":visible").slideUp(settings.hideSpeed, finished);
228					toShow.slideDown(settings.showSpeed, finished);
229				}
230			} else {
231				if ( !settings.alwaysOpen && clickedActive ) {
232					toShow.toggle();
233				} else {
234					toHide.hide();
235					toShow.show();
236				}
237				finished(true);
238			}
239
240			return false;
241		};
242		function activateHandlder(event, index) {
243			// call clickHandler with custom event
244			clickHandler({
245				target: jQuery(settings.header, this)[index]
246			});
247		};
248
249		return container
250			.bind(settings.event, clickHandler)
251			.bind("activate", activateHandlder);
252	},
253	// programmatic triggering
254	activate: function(index) {
255		return this.trigger('activate', [index || 0]);
256	}
257});
258
259jQuery.Accordion = {};
260jQuery.extend(jQuery.Accordion, {
261	defaults: {
262		selectedClass: "selected",
263		showSpeed: 'slow',
264		hideSpeed: 'fast',
265		alwaysOpen: true,
266		animated: true,
267		event: "click"
268	},
269	setDefaults: function(settings) {
270		jQuery.extend(jQuery.Accordion.defaults, settings);
271	}
272});

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.