Projet

Général

Profil

Paste
Télécharger (10 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / themes / mayo / js / mayo-columns.js @ 13c3c9b4

1
/**
2
* 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
  });
345
})(jQuery);