PageSourceSearch

https://www.joomlart.com/templates/ja_v5/js/right-height.js

js joomlart.com collected 2026-09-24 15:31:23 UTC 8,028 bytes, 301 lines download raw bytes

1/*!
2 * Right-Height v4.1.0: Dynamically set content areas of different lengths to the same height
3 * (c) 2015 Chris Ferdinandi
4 * MIT License
5 * http://github.com/cferdinandi/right-height
6 */
7
8(function (root, factory) {
9	if ( typeof define === 'function' && define.amd ) {
10		define([], factory(root));
11	} else if ( typeof exports === 'object' ) {
12		module.exports = factory(root);
13	} else {
14		root.rightHeight = factory(root);
15	}
16})(typeof global !== "undefined" ? global : this.window || this.global, function (root) {
17
18	'use strict';
19
20	//
21	// Variables
22	//
23
24	var rightHeight = {}; // Object for public APIs
25	var supports = 'querySelector' in document && 'addEventListener' in root; // Feature test
26	var settings, containers, eventTimeout;
27
28	// Default settings
29	var defaults = {
30		selector: '[data-right-height]',
31		selectorContent: '[data-right-height-content]',
32		callback: function () {}
33	};
34
35
36	//
37	// Methods
38	//
39
40	/**
41	 * A simple forEach() implementation for Arrays, Objects and NodeLists.
42	 * @private
43	 * @author Todd Motto
44	 * @link   https://github.com/toddmotto/foreach
45	 * @param {Array|Object|NodeList} collection Collection of items to iterate
46	 * @param {Function}              callback   Callback function for each iteration
47	 * @param {Array|Object|NodeList} scope      Object/NodeList/Array that forEach is iterating over (aka `this`)
48	 */
49	var forEach = function ( collection, callback, scope ) {
50		if ( Object.prototype.toString.call( collection ) === '[object Object]' ) {
51			for ( var prop in collection ) {
52				if ( Object.prototype.hasOwnProperty.call( collection, prop ) ) {
53					callback.call( scope, collection[prop], prop, collection );
54				}
55			}
56		} else {
57			for ( var i = 0, len = collection.length; i < len; i++ ) {
58				callback.call( scope, collection[i], i, collection );
59			}
60		}
61	};
62
63	/**
64	 * Merge two or more objects. Returns a new object.
65	 * @private
66	 * @param {Boolean}  deep     If true, do a deep (or recursive) merge [optional]
67	 * @param {Object}   objects  The objects to merge together
68	 * @returns {Object}          Merged values of defaults and options
69	 */
70	var extend = function () {
71
72		// Variables
73		var extended = {};
74		var deep = false;
75		var i = 0;
76		var length = arguments.length;
77
78		// Check if a deep merge
79		if ( Object.prototype.toString.call( arguments[0] ) === '[object Boolean]' ) {
80			deep = arguments[0];
81			i++;
82		}
83
84		// Merge the object into the extended object
85		var merge = function (obj) {
86			for ( var prop in obj ) {
87				if ( Object.prototype.hasOwnProperty.call( obj, prop ) ) {
88					// If deep merge and property is an object, merge properties
89					if ( deep && Object.prototype.toString.call(obj[prop]) === '[object Object]' ) {
90						extended[prop] = extend( true, extended[prop], obj[prop] );
91					} else {
92						extended[prop] = obj[prop];
93					}
94				}
95			}
96		};
97
98		// Loop through each object and conduct a merge
99		for ( ; i < length; i++ ) {
100			var obj = arguments[i];
101			merge(obj);
102		}
103
104		return extended;
105
106	};
107
108	/**
109	 * Get an element's distance from the top of the Document.
110	 * @private
111	 * @param  {Node} elem The element
112	 * @return {Number}    Distance from the top in pixels
113	 */
114	var getOffsetTop = function ( elem ) {
115		var location = 0;
116		if (elem.offsetParent) {
117			do {
118				location += elem.offsetTop;
119				elem = elem.offsetParent;
120			} while (elem);
121		}
122		return location >= 0 ? location : 0;
123	};
124
125	/**
126	 * Check if a group of content areas are stacked
127	 * @private
128	 * @param  {NodeList} contents A collection of content areas to compare
129	 * @return {Boolean} Returns true if elements are stacked
130	 */
131	var checkIfStacked = function ( contents ) {
132
133		// Selectors and variables
134		var contentFirst = contents.item(0);
135		var contentSecond = contents.item(1);
136
137		// Determine if content containers are stacked
138		if ( contentFirst && contentSecond ) {
139			if ( getOffsetTop(contentFirst) - getOffsetTop(contentSecond) === 0 ) {
140				return false;
141			} else {
142				return true;
143			}
144		} else {
145			return false;
146		}
147
148	};
149
150	/**
151	 * Reset the content height to 'auto'
152	 * @private
153	 * @param  {Element} content The content area to set to height: auto
154	 */
155	var resetHeight = function ( content ) {
156		content.style.height = '';
157		content.style.minHeight = '';
158	};
159
160	/**
161	 * Get the natural height of each content area, and
162	 * record the tallest height to set for all other elements.
163	 * @private
164	 * @param  {Element} content A content area
165	 * @param  {Number} height The current tallest height
166	 * @return {Number} The updated tallest height
167	 */
168	var getHeight = function ( content, height ) {
169		if ( content.offsetHeight > height ) {
170			height = content.offsetHeight;
171		}
172		return height;
173	};
174
175	/**
176	 * Set the height of each content area
177	 * @private
178	 * @param {Element} content The content area to set a height for
179	 * @param {Number} height The height of the tallest content area
180	 */
181	var setHeight = function ( content, height ) {
182		content.style.height = height + 'px';
183	};
184
185	/**
186	 * Get all content areas within a group
187	 * @public
188	 * @param  {Element} container The wrapper that contains a set of content areas
189	 * @param  {Object} options
190	 */
191	rightHeight.adjustContainerHeight = function ( container, options ) {
192
193		// Selectors and variables
194		var settings = extend( settings || defaults, options || {} );  // Merge user options with defaults
195		var contents = container.querySelectorAll( settings.selectorContent );
196		var isStacked = checkIfStacked(contents);
197		var height = '0';
198
199		// Reset each content area to its natural height
200		forEach(contents, function (content) {
201			resetHeight( content );
202		});
203
204		// If content areas are not stacked, give them equal heights
205		if ( !isStacked ) {
206			forEach(contents, function (content) {
207				height = getHeight( content, height );
208			});
209			forEach(contents, function (content) {
210				setHeight( content, height );
211			});
212		}
213
214		settings.callback( container ); // Run callbacks after adjust content
215
216	};
217
218	/**
219	 * For each group of content, adjust the content area heights
220	 * @private
221	 * @param  {NodeList} containers A collection of content wrappers
222	 * @param  {Object} settings
223	 */
224	var runRightHeight = function () {
225		forEach(containers, function (container) {
226			rightHeight.adjustContainerHeight( container, settings );
227		});
228	};
229
230	/**
231	 * On window resize, only run 'runRightHeight' at a rate of 15fps for better performance
232	 * @private
233	 * @param  {Function} eventTimeout Timeout function
234	 * @param  {NodeList} containers A collection of content wrappers
235	 * @param  {Object} settings
236	 */
237	var eventThrottler = function () {
238		if ( !eventTimeout ) {
239			eventTimeout = setTimeout(function() {
240				eventTimeout = null;
241				runRightHeight( containers, settings );
242			}, 66);
243		}
244	};
245
246	/**
247	 * Destroy the current initialization.
248	 * @public
249	 */
250	rightHeight.destroy = function () {
251
252		if (!settings) return;
253
254		// Reset content and remove event listeners
255		forEach(containers, function (container) {
256			var contents = container.querySelectorAll( settings.selectorContent );
257			forEach(contents, function (content) {
258				resetHeight( content );
259			});
260		});
261		root.removeEventListener('resize', eventThrottler, false);
262
263		// Reset variables
264		settings = null;
265		containers = null;
266		eventTimeout = null;
267
268	};
269
270	/**
271	 * Initialize Right Height
272	 * @public
273	 * @param {Object} options User settings
274	 */
275	rightHeight.init = function ( options ) {
276
277		// feature test
278		if ( !supports ) return;
279
280		// Destroy any existing initializations
281		rightHeight.destroy();
282
283		// Selectors and variables
284		settings = extend( defaults, options || {} ); // Merge user options with defaults
285		containers = document.querySelectorAll( settings.selector ); // Groups of content
286
287		// Events and listeners
288		runRightHeight( containers, options ); // Run Right Height on load
289		root.addEventListener('load', runRightHeight, false);
290		root.addEventListener('resize', eventThrottler, false); // Run Right Height on window resize
291
292	};
293
294
295	//
296	// Public APIs
297	//
298
299	return rightHeight;
300
301});

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.