vendor: 11,124 bytes, lines 1-368
1/** 2* jquery.matchHeight.js master 3* http://brm.io/jquery-match-height/ 4* License: MIT 5*/ 6 7;(function($) { // eslint-disable-line no-extra-semi 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.version = 'master'; 135 matchHeight._groups = []; 136 matchHeight._throttle = 80; 137 matchHeight._maintainScroll = false; 138 matchHeight._beforeUpdate = null; 139 matchHeight._afterUpdate = null; 140 matchHeight._rows = _rows; 141 matchHeight._parse = _parse; 142 matchHeight._parseOptions = _parseOptions; 143 144 /* 145 * matchHeight._apply 146 * apply matchHeight to given elements 147 */ 148 149 matchHeight._apply = function(elements, options) { 150 var opts = _parseOptions(options), 151 $elements = $(elements), 152 rows = [$elements]; 153 154 // take note of scroll position 155 var scrollTop = $(window).scrollTop(), 156 htmlHeight = $('html').outerHeight(true); 157 158 // get hidden parents 159 var $hiddenParents = $elements.parents().filter(':hidden'); 160 161 // cache the original inline style 162 $hiddenParents.each(function() { 163 var $that = $(this); 164 $that.data('style-cache', $that.attr('style')); 165 }); 166 167 // temporarily must force hidden parents visible 168 $hiddenParents.css('display', 'block'); 169 170 // get rows if using byRow, otherwise assume one row 171 if (opts.byRow && !opts.target) { 172 173 // must first force an arbitrary equal height so floating elements break evenly 174 $elements.each(function() { 175 var $that = $(this), 176 display = $that.css('display'); 177 178 // temporarily force a usable display value 179 if (display !== 'inline-block' && display !== 'inline-flex') { 180 display = 'block'; 181 } 182 183 // cache the original inline style 184 $that.data('style-cache', $that.attr('style')); 185 186 $that.css({ 187 'display': display, 188 'padding-top': '0', 189 'padding-bottom': '0', 190 'margin-top': '0', 191 'margin-bottom': '0', 192 'border-top-width': '0', 193 'border-bottom-width': '0', 194 'height': '100px', 195 'overflow': 'hidden' 196 }); 197 }); 198 199 // get the array of rows (based on element top position) 200 rows = _rows($elements); 201 202 // revert original inline styles 203 $elements.each(function() { 204 var $that = $(this); 205 $that.attr('style', $that.data('style-cache') || ''); 206 }); 207 } 208 209 $.each(rows, function(key, row) { 210 var $row = $(row), 211 targetHeight = 0; 212 213 if (!opts.target) { 214 // skip apply to rows with only one item 215 if (opts.byRow && $row.length <= 1) { 216 $row.css(opts.property, ''); 217 return; 218 } 219 220 // iterate the row and find the max height 221 $row.each(function(){ 222 var $that = $(this), 223 display = $that.css('display'); 224 225 // temporarily force a usable display value 226 if (display !== 'inline-block' && display !== 'inline-flex') { 227 display = 'block'; 228 } 229 230 // ensure we get the correct actual height (and not a previously set height value) 231 var css = { 'display': display }; 232 css[opts.property] = ''; 233 $that.css(css); 234 235 // find the max height (including padding, but not margin) 236 if ($that.outerHeight(false) > targetHeight) { 237 targetHeight = $that.outerHeight(false); 238 } 239 240 // revert display block 241 $that.css('display', ''); 242 }); 243 } else { 244 // if target set, use the height of the target element 245 targetHeight = opts.target.outerHeight(false); 246 } 247 248 // iterate the row and apply the height to all elements 249 $row.each(function(){ 250 var $that = $(this), 251 verticalPadding = 0; 252 253 // don't apply to a target 254 if (opts.target && $that.is(opts.target)) { 255 return; 256 } 257 258 // handle padding and border correctly (required when not using border-box) 259 if ($that.css('box-sizing') !== 'border-box') { 260 verticalPadding += _parse($that.css('border-top-width')) + _parse($that.css('border-bottom-width')); 261 verticalPadding += _parse($that.css('padding-top')) + _parse($that.css('padding-bottom')); 262 } 263 264 // set the height (accounting for padding and border) 265 $that.css(opts.property, (targetHeight - verticalPadding) + 'px'); 266 }); 267 }); 268 269 // revert hidden parents 270 $hiddenParents.each(function() { 271 var $that = $(this); 272 $that.attr('style', $that.data('style-cache') || null); 273 }); 274 275 // restore scroll position if enabled 276 if (matchHeight._maintainScroll) { 277 $(window).scrollTop((scrollTop / htmlHeight) * $('html').outerHeight(true)); 278 } 279 280 return this; 281 }; 282 283 /* 284 * matchHeight._applyDataApi 285 * applies matchHeight to all elements with a data-match-height attribute 286 */ 287 288 matchHeight._applyDataApi = function() { 289 var groups = {}; 290 291 // generate groups by their groupId set by elements using data-match-height 292 $('[data-match-height], [data-mh]').each(function() { 293 var $this = $(this), 294 groupId = $this.attr('data-mh') || $this.attr('data-match-height'); 295 296 if (groupId in groups) { 297 groups[groupId] = groups[groupId].add($this); 298 } else { 299 groups[groupId] = $this; 300 } 301 }); 302 303 // apply matchHeight to each group 304 $.each(groups, function() { 305 this.matchHeight(true); 306 }); 307 }; 308 309 /* 310 * matchHeight._update 311 * updates matchHeight on all current groups with their correct options 312 */ 313 314 var _update = function(event) { 315 if (matchHeight._beforeUpdate) { 316 matchHeight._beforeUpdate(event, matchHeight._groups); 317 } 318 319 $.each(matchHeight._groups, function() { 320 matchHeight._apply(this.elements, this.options); 321 }); 322 323 if (matchHeight._afterUpdate) { 324 matchHeight._afterUpdate(event, matchHeight._groups); 325 } 326 }; 327 328 matchHeight._update = function(throttle, event) { 329 // prevent update if fired from a resize event 330 // where the viewport width hasn't actually changed 331 // fixes an event looping bug in IE8 332 if (event && event.type === 'resize') { 333 var windowWidth = $(window).width(); 334 if (windowWidth === _previousResizeWidth) { 335 return; 336 } 337 _previousResizeWidth = windowWidth; 338 } 339 340 // throttle updates 341 if (!throttle) { 342 _update(event); 343 } else if (_updateTimeout === -1) { 344 _updateTimeout = setTimeout(function() { 345 _update(event); 346 _updateTimeout = -1; 347 }, matchHeight._throttle); 348 } 349 }; 350 351 /* 352 * bind events 353 */ 354 355 // apply on DOM ready event 356 $(matchHeight._applyDataApi); 357 358 // update heights on load and resize events 359 $(window).bind('load', function(event) { 360 matchHeight._update(false, event); 361 }); 362 363 // throttled update heights on resize events 364 $(window).bind('resize orientationchange', function(event) { 365 matchHeight._update(true, event); 366 }); 367 368})(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.