PageSourceSearch

https://blogs.hrz.tu-freiberg.de/fsr2/wp-content/themes/TUBAF_Theme/js/jquery.matchHeight.js

js tu-freiberg.de collected 2026-09-24 08:40:49 UTC 11,261 bytes, 363 lines download raw bytes

vendor: 10,926 bytes, lines 1-351
1/**
2* jquery.matchHeight.js master
3* http://brm.io/jquery-match-height/
4* License: MIT
5*/
6
7;(function($) {
8    /*
9    *  internal
10    */
11
12    var _previousResizeWidth = -1,
13        _updateTimeout = -1;
14
15    /*
16    *  _parse
17    *  value parse utility function
18    */
19
20    var _parse = function(value) {
21        // parse value and convert NaN to 0
22        return parseFloat(value) || 0;
23    };
24
25    /*
26    *  _rows
27    *  utility function returns array of jQuery selections representing each row
28    *  (as displayed after float wrapping applied by browser)
29    */
30
31    var _rows = function(elements) {
32        var tolerance = 1,
33            $elements = $(elements),
34            lastTop = null,
35            rows = [];
36
37        // group elements by their top position
38        $elements.each(function(){
39            var $that = $(this),
40                top = $that.offset().top - _parse($that.css('margin-top')),
41                lastRow = rows.length > 0 ? rows[rows.length - 1] : null;
42
43            if (lastRow === null) {
44                // first item on the row, so just push it
45                rows.push($that);
46            } else {
47                // if the row top is the same, add to the row group
48                if (Math.floor(Math.abs(lastTop - top)) <= tolerance) {
49                    rows[rows.length - 1] = lastRow.add($that);
50                } else {
51                    // otherwise start a new row group
52                    rows.push($that);
53                }
54            }
55
56            // keep track of the last row top
57            lastTop = top;
58        });
59
60        return rows;
61    };
62
63    /*
64    *  _parseOptions
65    *  handle plugin options
66    */
67
68    var _parseOptions = function(options) {
69        var opts = {
70            byRow: true,
71            property: 'height',
72            target: null,
73            remove: false
74        };
75
76        if (typeof options === 'object') {
77            return $.extend(opts, options);
78        }
79
80        if (typeof options === 'boolean') {
81            opts.byRow = options;
82        } else if (options === 'remove') {
83            opts.remove = true;
84        }
85
86        return opts;
87    };
88
89    /*
90    *  matchHeight
91    *  plugin definition
92    */
93
94    var matchHeight = $.fn.matchHeight = function(options) {
95        var opts = _parseOptions(options);
96
97        // handle remove
98        if (opts.remove) {
99            var that = this;
100
101            // remove fixed height from all selected elements
102            this.css(opts.property, '');
103
104            // remove selected elements from all groups
105            $.each(matchHeight._groups, function(key, group) {
106                group.elements = group.elements.not(that);
107            });
108
109            // TODO: cleanup empty groups
110
111            return this;
112        }
113
114        if (this.length <= 1 && !opts.target) {
115            return this;
116        }
117
118        // keep track of this group so we can re-apply later on load and resize events
119        matchHeight._groups.push({
120            elements: this,
121            options: opts
122        });
123
124        // match each element's height to the tallest element in the selection
125        matchHeight._apply(this, opts);
126
127        return this;
128    };
129
130    /*
131    *  plugin global options
132    */
133
134    matchHeight._groups = [];
135    matchHeight._throttle = 80;
136    matchHeight._maintainScroll = false;
137    matchHeight._beforeUpdate = null;
138    matchHeight._afterUpdate = null;
139
140    /*
141    *  matchHeight._apply
142    *  apply matchHeight to given elements
143    */
144
145    matchHeight._apply = function(elements, options) {
146        var opts = _parseOptions(options),
147            $elements = $(elements),
148            rows = [$elements];
149
150        // take note of scroll position
151        var scrollTop = $(window).scrollTop(),
152            htmlHeight = $('html').outerHeight(true);
153
154        // get hidden parents
155        var $hiddenParents = $elements.parents().filter(':hidden');
156
157        // cache the original inline style
158        $hiddenParents.each(function() {
159            var $that = $(this);
160            $that.data('style-cache', $that.attr('style'));
161        });
162
163        // temporarily must force hidden parents visible
164        $hiddenParents.css('display', 'block');
165
166        // get rows if using byRow, otherwise assume one row
167        if (opts.byRow && !opts.target) {
168
169            // must first force an arbitrary equal height so floating elements break evenly
170            $elements.each(function() {
171                var $that = $(this),
172                    display = $that.css('display');
173
174                // temporarily force a usable display value
175                if (display !== 'inline-block' && display !== 'inline-flex') {
176                    display = 'block';
177                }
178
179                // cache the original inline style
180                $that.data('style-cache', $that.attr('style'));
181
182                $that.css({
183                    'display': display,
184                    'padding-top': '0',
185                    'padding-bottom': '0',
186                    'margin-top': '0',
187                    'margin-bottom': '0',
188                    'border-top-width': '0',
189                    'border-bottom-width': '0',
190                    'height': '100px'
191                });
192            });
193
194            // get the array of rows (based on element top position)
195            rows = _rows($elements);
196
197            // revert original inline styles
198            $elements.each(function() {
199                var $that = $(this);
200                $that.attr('style', $that.data('style-cache') || '');
201            });
202        }
203
204        $.each(rows, function(key, row) {
205            var $row = $(row),
206                targetHeight = 0;
207
208            if (!opts.target) {
209                // skip apply to rows with only one item
210                if (opts.byRow && $row.length <= 1) {
211                    $row.css(opts.property, '');
212                    return;
213                }
214
215                // iterate the row and find the max height
216                $row.each(function(){
217                    var $that = $(this),
218                        display = $that.css('display');
219
220                    // temporarily force a usable display value
221                    if (display !== 'inline-block' && display !== 'inline-flex') {
222                        display = 'block';
223                    }
224
225                    // ensure we get the correct actual height (and not a previously set height value)
226                    var css = { 'display': display };
227                    css[opts.property] = '';
228                    $that.css(css);
229
230                    // find the max height (including padding, but not margin)
231                    if ($that.outerHeight(false) > targetHeight) {
232                        targetHeight = $that.outerHeight(false);
233                    }
234
235                    // revert display block
236                    $that.css('display', '');
237                });
238            } else {
239                // if target set, use the height of the target element
240                targetHeight = opts.target.outerHeight(false);
241            }
242
243            // iterate the row and apply the height to all elements
244            $row.each(function(){
245                var $that = $(this),
246                    verticalPadding = 0;
247
248                // don't apply to a target
249                if (opts.target && $that.is(opts.target)) {
250                    return;
251                }
252
253                // handle padding and border correctly (required when not using border-box)
254                if ($that.css('box-sizing') !== 'border-box') {
255                    verticalPadding += _parse($that.css('border-top-width')) + _parse($that.css('border-bottom-width'));
256                    verticalPadding += _parse($that.css('padding-top')) + _parse($that.css('padding-bottom'));
257                }
258
259                // set the height (accounting for padding and border)
260                $that.css(opts.property, (targetHeight - verticalPadding) + 'px');
261            });
262        });
263
264        // revert hidden parents
265        $hiddenParents.each(function() {
266            var $that = $(this);
267            $that.attr('style', $that.data('style-cache') || null);
268        });
269
270        // restore scroll position if enabled
271        if (matchHeight._maintainScroll) {
272            $(window).scrollTop((scrollTop / htmlHeight) * $('html').outerHeight(true));
273        }
274
275        return this;
276    };
277
278    /*
279    *  matchHeight._applyDataApi
280    *  applies matchHeight to all elements with a data-match-height attribute
281    */
282
283    matchHeight._applyDataApi = function() {
284        var groups = {};
285
286        // generate groups by their groupId set by elements using data-match-height
287        $('[data-match-height], [data-mh]').each(function() {
288            var $this = $(this),
289                groupId = $this.attr('data-mh') || $this.attr('data-match-height');
290
291            if (groupId in groups) {
292                groups[groupId] = groups[groupId].add($this);
293            } else {
294                groups[groupId] = $this;
295            }
296        });
297
298        // apply matchHeight to each group
299        $.each(groups, function() {
300            this.matchHeight(true);
301        });
302    };
303
304    /*
305    *  matchHeight._update
306    *  updates matchHeight on all current groups with their correct options
307    */
308
309    var _update = function(event) {
310        if (matchHeight._beforeUpdate) {
311            matchHeight._beforeUpdate(event, matchHeight._groups);
312        }
313
314        $.each(matchHeight._groups, function() {
315            matchHeight._apply(this.elements, this.options);
316        });
317
318        if (matchHeight._afterUpdate) {
319            matchHeight._afterUpdate(event, matchHeight._groups);
320        }
321    };
322
323    matchHeight._update = function(throttle, event) {
324        // prevent update if fired from a resize event
325        // where the viewport width hasn't actually changed
326        // fixes an event looping bug in IE8
327        if (event && event.type === 'resize') {
328            var windowWidth = $(window).width();
329            if (windowWidth === _previousResizeWidth) {
330                return;
331            }
332            _previousResizeWidth = windowWidth;
333        }
334
335        // throttle updates
336        if (!throttle) {
337            _update(event);
338        } else if (_updateTimeout === -1) {
339            _updateTimeout = setTimeout(function() {
340                _update(event);
341                _updateTimeout = -1;
342            }, matchHeight._throttle);
343        }
344    };
345
346    /*
347    *  bind events
348    */
349
350    // apply on DOM ready event
351    $(matchHeight._applyDataApi);
352
353    // update heights on load and resize events
354    $(window).bind('load', function(event) {
355        matchHeight._update(false, event);
356    });
357
358    // throttled update heights on resize events
359    $(window).bind('resize orientationchange', function(event) {
360        matchHeight._update(true, event);
361    });
362
363})(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.