Skip to content

Instantly share code, notes, and snippets.

@anutron
Created March 20, 2009 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anutron/82547 to your computer and use it in GitHub Desktop.
Save anutron/82547 to your computer and use it in GitHub Desktop.
/*
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