---------------------
1) To get a node's dimensions (including padding and border):
offsetHeight, offsetWidth (works everywhere except IE5 on Mac)
2) To get dimensions without border but includes padding: clientHeight, clientWidth (works everywhere except IE5 on Mac)
There's no API to get dims excluding both padding and border.
3) If node's overflow is set to "hidden" and some part of the element has been cut off, then scrollHeight, scrollWidth gives the full dimensions including the hidden portions.
Of course you'll use a library for these. Let's compare 2 implementations:
1) mootools - In Element.Dimensions.js you find:
getSize: function(){
... 'size': {'x': this.offsetWidth, 'y': this.offsetHeight},
'scrollSize': {'x': this.scrollWidth, 'y': this.scrollHeight}
...
}
2) YUI - in dom/dom.js you find:
YAHOO.util.Region.getRegion = function(el) {
...
var r = p[0] + el.offsetWidth;
var b = p[1] + el.offsetHeight;
...
}
References: Quirksmode, Sitepoint
Viewport dimensions
-------------------------
This API varies with browser and Doctype mode. In particular, IE gives it in different ways depending on whether it's running in Standards compliance mode or not. So you need 3 branches: one for IE in quirks mode, one for IE in Standards mode, and the 3rd for all other browsers. If you know for sure that the page will have a Doctype (which is very likely for new apps), then you can omit the "quirks mode in IE" test.
The properties of interest are innerWidth, innerHeight (Non-IE browsers) and clientHeight, clientWidth (IE). In Standards mode, the IE property should be read from document.documentElement, and in quirks mode it's read from document.body (whew!).
So the code becomes (note: use self instead of window so that your code works even if the page is framed):
if(self.innerHeight) { //all Non-IE..you can also check for innerWidth here
height = self.innerHeight, width = self.innerWidth;
}else{ // for IE
//in Standards mode, read from documentElement
if(document.documentElement && document.documentElement.clientHeight){
height = document.documentElement.clientHeight;
width = document.documentElement.clientWidth;
}else{
//Quirks mode of IE, read from document.body
height = document.body.clientHeight;
width = document.body.clientWidth;
}
}
YUI takes a slightly different approach, probably because it results in fewer lines of code. They make use of the fact that Mozilla browsers support both innerWidth, innerHeight and the IE properties. So inner* are effectively for Safari.
In dom/dom.js, you'll find:
Here, document.compatMode is used to check the Standards mode. It returns "BackCompat" if no Doctype and "CSS1Compat" if in Standards mode.
getViewportWidth: function() {
var width = self.innerWidth; // Safari
var mode = document.compatMode;
if (mode || isIE) { // IE, Gecko, Opera
width = (mode == 'CSS1Compat') ?
document.documentElement.clientWidth : // Standards
document.body.clientWidth; // Quirks
}
return width;
}
Scroll offsets - how much the page has scrolled
---------------------
This follows the viewport size model: one branch for Non-IE, and one each for IE in Standards and Quirks mode. For IE, you read the scrollLeft, scrollTop from documentElement or document.body. For others, it's self.pageXOffset, pageYOffset.
So the code would be:
Here, YUI again makes use of the fact that all browsers support the non-W3C, IE-invented scrollTop and scrollLeft. Nothing wrong in that, and results in a simple one-liner in dom/dom.js:
if (typeof(self.pageYOffset) != 'undefined' ){ // all but
x = self.pageXOffset;
y = self.pageYOffset;
}else if (document.documentElement &&
typeof(document.documentElement.scrollTop)!='undefined'){
// IE Standards mode
x = document.documentElement.scrollLeft;
y = document.documentElement.scrollTop;
}else if(document.body){ // IE Quirks mode
x = document.body.scrollLeft;
y = document.body.scrollTop;
}
getDocumentScrollTop: function(){Math.max() works because in Standards mode, the property on the document.body is always zero and vice-versa.
return Math.max(document.documentElement.scrollTop, document.body.scrollTop);
}
No comments:
Post a Comment