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