由clientWidth到document

引言

最近想用js写一些插件,其中一点就是要获取浏览器可视窗口的宽度或高度,以及相对于文档的偏移等等。我们知道用JQuery用起来很爽快,你可以通过

$(window).width() 获取宽度

$(window).height() 获取高度

$(ele).offset().top 相对于浏览器顶部的偏移

$(ele).offset().left 相对于浏览器左边的偏移

我们来看看jQuery源码:

        offset: function(a) {
            if (arguments.length)
                return void 0 === a ? this : this.each(function(b) {
                    m.offset.setOffset(this, a, b)
                });
            var b, c, d = {
                top: 0,
                left: 0
            }, e = this[0], f = e && e.ownerDocument;
            if (f)
                return b = f.documentElement,
                m.contains(b, e) ? (typeof e.getBoundingClientRect !== K && (d = e.getBoundingClientRect()),
                c = dd(f),
                {
                    top: d.top + (c.pageYOffset || b.scrollTop) - (b.clientTop || 0),
                    left: d.left + (c.pageXOffset || b.scrollLeft) - (b.clientLeft || 0)
                }) : d
        },
        position: function() {
            if (this[0]) {
                var a, b, c = {
                    top: 0,
                    left: 0
                }, d = this[0];
                return "fixed" === m.css(d, "position") ? b = d.getBoundingClientRect() : (a = this.offsetParent(),
                b = this.offset(),
                m.nodeName(a[0], "html") || (c = a.offset()),
                c.top += m.css(a[0], "borderTopWidth", !0),
                c.left += m.css(a[0], "borderLeftWidth", !0)),
                {
                    top: b.top - c.top - m.css(d, "marginTop", !0),
                    left: b.left - c.left - m.css(d, "marginLeft", !0)
                }
            }
        }
ownerDocument 是个什么东西?我们随便写个div盒子,起个id为box,打印一下
> document.getElementById('box').ownerDocument.nodeName
> #document
嗦嘎,原来这样可以获取到document对象!出于好奇我继续打印下面的结果:
> document.getElementById('box').ownerDocument.documentElement.nodeName;
> HTML
> document.getElementById('box').ownerDocument.body.nodeName;
> BODY

到这里,你可能对ownerDocument还不是太熟悉,但你一定经常看到过 document.documentElement.clientWidth 与 docuemnt.body.clientWidth这样的代码,没错,今天的问题就此而展开。

正文

为了写出兼容老版本浏览器的代码,我们需要通过document.compatMode判断当前浏览器处于什么模式。是quirksMode 还是 standradMode?standradMode也叫strict mode。

什么是怪异模式呢?

在早期W3C标准还没出来之前,一些浏览器比如netscape、Explorer 4 都按照浏览器自己的方式进行解析,他们各自为政,所以被称为怪异模式。标准模式则自然是W3C颁布的标准咯!

如何区分标准模式和怪异模式呢?

       Ⅰ 区分标准模式和怪异模式与文档Doctype声明有关,对于没有该声明的,浏览器将采用quirks mode

       Ⅱ 对于有Doctype声明的,没有使用DTD声明或者使用HTML4以下的DTD声明时,则采用quirks mode

       Ⅲ 在我们现在开发网页中,一般都使用h5标准头<!Doctype html>,其采用的是标准模式strict mode

更多关于怪异模式和标准模式,可以去参考其他资料:http://hsivonen.iki.fi/doctype

现在我们知道了这两种模式之后,那么如何用代码判断呢?各浏览器对document提供了一个叫compatMode的属性,他有两个值:

1. BackCompat 

2. CSS1Compat

当compatMode的值为CSS1Compat,我们使用document.documentElement

当compatMode的值为BackCompat,我们使用document.body,固有:

clientWidth = document.compatMode == 'CSS1Compat' ? document.documentElement.clientWidth : document.body.clientWidth;

clientHeight = document.compatMode == 'CSS1Compat' ? document.documentElement.clientHeight : document.body.clientHeight;

原文地址:https://www.cnblogs.com/dzyBlog/p/4901761.html