Created
March 20, 2009 19:59
-
-
Save anutron/82547 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Script: Element.Measure.js | |
Extends the Element native object to include methods useful in measuring dimensions. | |
Element.measure / .expose methods by Daniel Steigerwald | |
License: MIT-style license. | |
Copyright: Copyright (c) 2008 Daniel Steigerwald, daniel.steigerwald.cz | |
License: | |
MIT-style license. | |
Authors: | |
Aaron Newton | |
Daniel Steigerwald | |
*/ | |
Element.implement({ | |
measure: function(fn){ | |
var restore = this.expose(); | |
var result = fn.apply(this); | |
restore(); | |
return result; | |
}, | |
measureUp: function(fn){ | |
var parent = this.getParent(), | |
toMeasure = [], restorers = [], | |
vis = function(el) { | |
return !!(el.offSetHeight || el.offsetWidth); | |
}; | |
while (!vis(parent) && parent != document.body) { | |
toMeasure.push(parent.expose()); | |
parent = parent.getParent(); | |
} | |
var result = this.measure(fn); | |
toMeasure.each(function(restore){ | |
restore(); | |
}); | |
return result | |
}, | |
expose: function(){ | |
if (this.getStyle('display') != 'none') return $empty; | |
var before = {}; | |
var styles = { visibility: 'hidden', display: 'block', position:'absolute' }; | |
$each(styles, function(value, style){ | |
before[style] = this.style[style]||''; | |
}, this); | |
this.setStyles(styles); | |
return (function(){ this.setStyles(before); }).bind(this); | |
}, | |
getDimensions: function(options){ | |
options = $merge({computeSize: false},options); | |
var dim = {}; | |
var getSize = function(el, options){ | |
return (options.computeSize)?el.getComputedSize(options):el.getSize(); | |
}; | |
if (this.getStyle('display') == 'none'){ | |
dim = this.measure(function(){ | |
return getSize(this, options); | |
}); | |
} else { | |
try { //safari sometimes crashes here, so catch it | |
dim = getSize(this, options); | |
}catch(e){} | |
} | |
return $chk(dim.x) ? $extend(dim, {width: dim.x, height: dim.y}) : $extend(dim, {x: dim.width, y: dim.height}); | |
}, | |
getComputedSize: function(options){ | |
options = $merge({ | |
styles: ['padding','border'], | |
plains: { | |
height: ['top','bottom'], | |
width: ['left','right'] | |
}, | |
mode: 'both' | |
}, options); | |
var size = {width: 0,height: 0}; | |
switch (options.mode){ | |
case 'vertical': | |
delete size.width; | |
delete options.plains.width; | |
break; | |
case 'horizontal': | |
delete size.height; | |
delete options.plains.height; | |
break; | |
}; | |
var getStyles = []; | |
//this function might be useful in other places; perhaps it should be outside this function? | |
$each(options.plains, function(plain, key){ | |
plain.each(function(edge){ | |
options.styles.each(function(style){ | |
getStyles.push((style == "border") ? style + '-' + edge + '-' + 'width' : style + '-' + edge); | |
}); | |
}); | |
}); | |
var styles = this.getStyles.apply(this, getStyles); | |
var subtracted = []; | |
$each(options.plains, function(plain, key){ //keys: width, height, plains: ['left', 'right'], ['top','bottom'] | |
size['total' + key.capitalize()] = 0; | |
size['computed' + key.capitalize()] = 0; | |
plain.each(function(edge){ //top, left, right, bottom | |
size['computed' + edge.capitalize()] = 0; | |
getStyles.each(function(style, i){ //padding, border, etc. | |
//'padding-left'.test('left') size['totalWidth'] = size['width'] + [padding-left] | |
if (style.test(edge)){ | |
styles[style] = styles[style].toInt(); //styles['padding-left'] = 5; | |
if (isNaN(styles[style]))styles[style] = 0; | |
size['total' + key.capitalize()] = size['total' + key.capitalize()] + styles[style]; | |
size['computed' + edge.capitalize()] = size['computed' + edge.capitalize()] + styles[style]; | |
} | |
//if width != width (so, padding-left, for instance), then subtract that from the total | |
if (style.test(edge) && key != style && | |
(style.test('border') || style.test('padding')) && !subtracted.contains(style)){ | |
subtracted.push(style); | |
size['computed' + key.capitalize()] = size['computed' + key.capitalize()]-styles[style]; | |
} | |
}); | |
}); | |
}); | |
['Width', 'Height'].each(function(value){ | |
var lower = value.toLowerCase(); | |
if(!$chk(size[lower])) return; | |
size[lower] = size[lower] + this['offset' + value] + size['computed' + value]; | |
size['total' + value] = size[lower] + size['total' + value]; | |
delete size['computed' + value]; | |
}, this); | |
return $extend(styles, size); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment