PageSourceSearch

https://www.funabashi-multilingual.info/js/jquery.matchHeight.js

js funabashi-multilingual.info collected 2026-10-02 21:13:40 UTC 11,786 bytes, 396 lines download raw bytes

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

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.