Confused by document dimensions in JavaScript

梦想的初衷 提交于 2019-11-30 15:55:25
dkugappi

I'll try to answer as simply as I can.

The Document and Viewport

In terms of geometry, there are two sets of dimensions to be aware of; the document dimensions, which reflect the entire size of the loaded page, including the content beyond the bottom of the window and the viewport dimensions, which reflect the size of the visible part of the document that is immediately displayed in the window.

When you scroll down, the viewport moves down over the document by a certain number of pixels. In other words, the viewport is the actual browser window "border" (the toolbars, menus, tabs, and so on).

The confusion comes from the fact that depending on the browser and mode, different properties are used to get the dimensions of a document and viewport, and they return different results depending on scrollbars. But we'll come back to this.

Dimensions Overview

There are a number of properties available to you from the get-go in javascript which give you different dimensions.

  1. Screen resolution: window.screen.width -Height

  2. Available screen space (same as monitor resolution) minus docks, toolbars and other UI elements: window.screen.availWidth -Height.

  3. Document dimensions: document.documentElement.offsetWidth -Height Note: These numbers do not include the scrollbars.

  4. Viewport dimensions: window.innerWidth -Height

    • These numbers include the scrollbars.

    • This is not available in IE 8- and IE9, so if IE, test for the document.compatMode === "CSS1Compat" and if true, use document.documentElement.clientWidth -Height, and for quirks mode use document.body.clientWidth -Height.

A note about document dimensions

As per above, document.documentElement.offsetWidth/Height provides you with the actual size of the document. One caveat to this is that scrollbars work differently between browsers. For example, IE9 will always display a vertical scrollbar even if the document height is less than the viewport height. Safari/Chrome doesn't have scrollbars on OS X Lion. Chrome on PC will not display vertical scrollbars unless it needs to.

So you may bump into inconsistencies and the Scrollbar shifts content problem. Imagine you have an absolutely positioned and centred element. Because CSS calculates the "centre" relative to the document dimensions and not the viewport dimensions, when say, Google adds the scrollbars, your content may "jump" a bit to the left as the "document centre" changes. So you may need to write JS to compensate for this effect if it bothers you, or maybe someone here can write a quick JS function to calculate document dimensions with scrollbars included.

Scrollbar Position and Dimensions

While some methods in JavaScript work with document coordinates, others work with viewport coordinates, and often this is not what you want. For example, if you have an element's top edge at 20px in document coordinates, and you scroll the page down by 20px, the top edge of that element will be at 0px relative to the top viewport coordinate. So to convert between the two systems, you first need to know by how many pixels a user has scrolled the document, and then add that number to the viewport to compensate (look at example below).

I also found these helpful:

http://www.howtocreate.co.uk/tutorials/javascript/browserwindow

http://www.quirksmode.org/mobile/viewports.html

And here's a quick cross-browser module I mucked up to help you:

var dimensions = (function(){

    var dims = {};

    // get screen width/height:
    dims.screenWidth = function() { window.screen.width };
    dims.screenHeight = function() { return window.screen.height };

    // get screen width/height minus chrome:
    dims.availWidth = function() { return window.screen.availWidth };
    dims.availHeight = function() { return window.screen.availHeight };

    // get document width/height (with-out scrollbars):
    if (window.document.compatMode == "CSS1Compat"){ // if IE Standards Mode
        dims.documentWidth = function() { return document.body.offsetWidth };
        dims.documentHeight = function() { return document.body.offsetHeight };
    }
    else {
        dims.documentWidth = function() { return document.documentElement.offsetWidth };
        dims.documentHeight = function() { return document.documentElement.offsetHeight };
    }

    // get viewport width/height (with scrollbars):
    if (window.innerWidth != null) {
        dims.viewportWidth = function () { return window.innerWidth };
        dims.viewportHeight = function () { return window.innerHeight };
    }

        // if IE in Standards Mode
        else if (window.document.compatMode == "CSS1Compat"){
            dims.viewportWidth = function () { 
                return window.document.documentElement.clientWidth
            };
            dims.viewportHeight = function () { 
                return window.document.documentElement.clientHeight
            };
        }

    // get scrollbar offsets:
    if (window.pageXOffset != null) {
        dims.scrollXOffset = function() { return window.pageXOffset };
        dims.scrollYOffset = function() { return window.pageYOffset };
    }

        // if IE in Standards Mode
        else if (window.document.compatMode == "CSS1Compat"){
            dims.scrollXOffset = function() { return document.documentElement.scrollLeft };
            dims.scrollYOffset = function() { return document.documentElement.scrollTop };  
        }

    return dims;
}());

You can for example do console.log(dimensions.viewportWidth()) to get the viewport width.

Hope this helps you :)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!