Prev: How Internet Explorer 8 document mode affects JavaScript - Nicholas Zakas
Next: How to remove an element?
From: FAQ server on 18 Jun 2010 19:00 ----------------------------------------------------------------------- FAQ Topic - How do I find the size of the window? ----------------------------------------------------------------------- Here is a detailed explanation of a cross-browser strategy to find the dimensions of the viewport, excepting all chrome (excludes scrollbars, etc). We can consider various properties: window.innerWidth document.clientWidth document.documentElement.clientWidth document.body.clientWidth Of the browsers that have an ` innerWidth ` property, most include scrollbar dimensions. Some versions of KHTML browsers (including Safari 2) do _not_ include scrollbar width. The ` window.inner* ` properties are unreliable and not useful here. We don't want scrollbar dimensions included. document.clientWidth Certain versions of KHTML, including Safari 2, have ` document.clientHeight ` and ` document.clientWidth ` properties. Where supported, these rare properties accurately return the height and width of the viewport, without including scrollbar dimensions. document.documentElement.clientWidth document.body.clientWidth MSHTML (Trident), Firefox (Gecko), Opera (Presto), and Safari (Webkit) all support ` clientHeight ` on ` document.body ` and ` document.documentElement `. The difficulty is figuring out which one is reliable. In other words which object to get the ` clientHeight ` property from:` documentElement ` or ` body `? What the number returned from either of these properties represents depends on the environment. The environment includes the browser, its version, and the rendering mode of the document. In quirks mode, we'll mostly want to use ` body.clientHeight ` (except for in Safari 2). document.body.clientHeight Some environments will return the viewport height. Others will return ` 0 `. Yet others will return the ` clientHeight ` of the ` BODY ` element. document.documentElement.clientHeight This is the more "standard" property for getting the height of the viewport. It usually "works" in modern browsers in standards mode. Notable exceptions include Safari 2 and Opera <= 9.25, both of which return the ` clientHeight ` of the ` html ` _element_. (Oddly, Opera <= 9.25 in standards mode returns the width of the viewport for ` documentElement.clientWidth `). With the exception of Safari 2, ` body.clientHeight ` is reliable where ` documentElement.clientHeight ` is found to be unreliable. For example, in Safari 3+, Opera, and Mozilla, all in quirks mode, ` document.documentElement.clientHeight ` returns the ` clientHeight ` of the ` html ` element (this may seem unsurprising but it is not what we want). Conversely, ` document.body.clientHeight ` will return the height of the viewport in most cases where ` document.documentElement.clientHeight ` does not. An exception to that is Safari 2, where ` documentElement.clientHeight ` and ` body.clientHeight ` both return the height of their corresponding element (not what we want). By using a combination of Feature Testing and Capability Testing, the dimensions of the viewport can be strategically retrieved from the property that works in the environment the script is running in. The trick is determining which property will give us the value we want. Since ` document.clientHeight ` is reliable where (rarely) supported, and since browsers that support this property don't return the viewport dimensions from ` document.body.clientHeight ` or ` document.documentElement.clientHeight `, this should be the very first condition: // Safari 2 uses document.clientWidth (default). if(typeof document.clientWidth == "number") { // use document.clientWidth. } The next strategy is to determine if ` document.documentElement.clientHeight ` property is unreliable. It is deemed "unreliable" when it is either ` 0 ` or taller than the viewport. Determining if ` documentElement.clientHeight ` is ` 0 ` is easy. The result is stored in a variable ` IS_BODY_ACTING_ROOT `. var docEl = document.documentElement, IS_BODY_ACTING_ROOT = docEl && docEl.clientHeight === 0; docEl = null; To determine if ` documentElement.clientHeight ` returns a value taller than the viewport, we need a Capability Test. If we can force ` documentElement ` to be very tall (taller than a normal viewport) we can then check to see if ` documentElement.clientHeight ` returns that "very tall" number. If it does, then it is unreliable. We can force ` documentElement ` to be taller than the viewport (or any "normal" viewport) by adding a ` div ` to the ` body `, give that ` div ` a height larger than any normal monitor, and then check to see if ` documentElement.clientHeight ` is that high (or "almost" that high, to account for ` documentElement ` having a border). // Used to feature test Opera returning wrong values // for documentElement.clientHeight. // The results of this function should be cached, // so it does not need to be called more than once. function isDocumentElementHeightOff(){ var d = document, div = d.createElement('div'); div.style.height = "2500px"; d.body.insertBefore(div, d.body.firstChild); var r = d.documentElement.clientHeight > 2400; d.body.removeChild(div); return r; } We can use this function to see if we should use ` body.clientHeight `, instead. (but only after checking if ` document.clientHeight ` is supported). // Safari 2 uses document.clientWidth (default). if(typeof document.clientWidth == "number") { // use document.clientHeight/Width. } else if(IS_BODY_ACTING_ROOT || isDocumentElementHeightOff()) { // use document.body.clientHeight/Width. } else { // use document.documentElement.clientHeight/Width. } The preceding strategy was developed by Garrett Smith with input from John David Dalton. A complete and tested example can be found in APE Library under ` APE.dom.getViewportDimensions `. Source code: http://dhtmlkitchen.com/ape/build/dom/viewport-f.js APE is publicly released under Academic Free License. APE home: http://dhtmlkitchen.com/ape/ Note: The dimensions cannot be determined accurately until after the document has finished loading. http://msdn.microsoft.com/en-us/library/ms533566%28VS.85%29.aspx http://developer.mozilla.org/en/DOM/window.innerWidth http://dev.opera.com/articles/view/using-capability-detection/ The complete comp.lang.javascript FAQ is at http://jibbering.com/faq/ -- The sendings of these daily posts are proficiently hosted by http://www.pair.com. |