Document.defaultView

引子

最近愚安在写一个可以将页面上的资源链接转为二维码以方便移动端浏览的chrome插件,由于dom操作并不多,而且作为插件不需要考虑跨

浏览器兼容性,所以并没有引入jQuery,而是使用原生的DOM API。其中有一个需求是判断元素在页面上的相对文档的偏移offset。我使用

的方法如下:

function getOffset(ele){
if (!ele || ele.nodeType != 1) {
return;
}
var rect = ele.getBoundingClientRect(),
doc = ele.ownerDocument.documentElement; return {
top: rect.top + window.pageYOffset - doc.clientTop,
left: rect.left + window.pageXOffset - doc.clientLeft
}; }

因为以前看过一点jQuery的源码,又不需要注意兼容,所以写起来还是比较顺手的。这个方法,写出来还算是挺好用的,没发现什么问题,

得意之时,想着,要不去看下jQuery是怎么写的,翻了下,源码如下(version 2.1.1)

offset: function(options) {
if (arguments.length) {
return options === undefined ?
this :
this.each(function(i) {
jQuery.offset.setOffset(this, options, i);
});
} var docElem, win,
elem = this[0],
box = {
top: 0,
left: 0
},
doc = elem && elem.ownerDocument; if (!doc) {
return;
} docElem = doc.documentElement; // Make sure it's not a disconnected DOM node
if (!jQuery.contains(docElem, elem)) {
return box;
} // If we don't have gBCR, just use 0,0 rather than error
// BlackBerry 5, iOS 3 (original iPhone)
if (typeof elem.getBoundingClientRect !== strundefined) {
box = elem.getBoundingClientRect();
}
win = getWindow(doc);
return {
top: box.top + win.pageYOffset - docElem.clientTop,
left: box.left + win.pageXOffset - docElem.clientLeft
};
}

看了下,除了一些兼容性处理,和一些对jQuery对象的操作外,基本和我的做法是一样的,哈哈哈!突然瞄到了这么个东西win = getWindow(doc),

赶紧看下源码

function getWindow(elem) {
return jQuery.isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView;
}

ちょっと待って,defaultView是什么东西呢,我们知道nodeType为9时,该元素就是document,由于之前没有使用过,

document.defaultView的结果和我代码里的window对象有什么不同呢?

控制台查看

document.defaultView === window
//true

靠,这有什么意义呢,是jQuery的装B写法么?

查看DOM API文档

打开MDN,我找到了关于defaultView的描述

,稍翻一下

Document.defaultView

概要:

在浏览器中返回关联document的window对象,如果没有则返回null

用法:

var win = document.defaultView;

这是一个只读属性。

注意:

在quirksmode模式下, IE 9 以下版本不支持defaultView.

测试

好了,既然有这么个API自然是有他的用途的,MDN的文档表示defaultView是document关联的window对象,那么其用途肯定体现在当前上下文的window

不等于当前document关联的window时,即window !== document.defaultView,那么什么上下文(context)会出现这种情况呢,我想到了三种:

1.frame;2.popup;3.extension

开测:

1.frame

index.html

<html>
<head>
</head>
<body>
<iframe src="frame.html" id="myframe" name="myframe">
</iframe>
<script>
</script>
</body>
</html>

frame.html

<html>
<head>
</head>
<body>
<p>I'm iFrame</p>
<script>
console.log(window === document.defaultView);
</script>
</body>
</html>

测试结果:true

2.pupup

var open = window.open('frame.html');

测试结果:true

3.extension

在我写的这个chromePlugin里我分别在background.js和content.js里测试

无一例外window === document.defaultView都返回true。

这时我想到了firefox的扩展,但自己没有开发FF扩展的经验,就去google了一下,发现了这个,

大致意思是说,“如果你的扩展运行在FireFox 31以下的版本,在content.js里必须使用document.defaultView.postMessage”。

看到这里,我忽然想起jQuery源码中的defaultView也许就是为了兼容某些Firefox版本,哈哈,继续Google

终于,让我在MDN上找到了这个传送门

In many code samples online, getComputedStyle is used from the document.defaultView object. In nearly all cases, this is needless, as getComputedStyle exists on the window object as well. It's likely the defaultView pattern was some combination of (1) folks not wanting to write a spec for window and (2) making an API that was also usable in Java. However, there is a single case where the defaultView's method must be used: when using Firefox 3.6 to access framed styles.

很显然,坑就在这里了,当使用Firefox 3.6时,其frame中需要使用document.defaultView去获取window对象,才能使用其getComputedStyle方法。

好了,这个问题告一段落。

后记

不止一次听人抱怨jQuery的代码是多么的糟(qiang)糕(da),其运用大量的黑魔法,各种奇技淫巧去兼容所有的浏览器,即使已到2.1.1版本,仍然保持着对FF低版本的支持。

想想看在那个前端开发,还处在蛮荒的时代,jQuery的出现,还真是里程碑意义的事件,他极大力度的解放了前端的生产力,让前端开发人员,

有时间和精力去开发各种前端工具,规范,才有了大前端时代的来临。哈哈,吹的有点多,干货略少。

Document.defaultView的更多相关文章

  1. JS中使用document.defaultView.getComputedStyle()、currentStyle()方法获取CSS属性值

    在对网页进行调试的过程中,经常会用到js来获取元素的CSS样式,方法有很多很多,现在仅把我经常用的方法总结如: 1. obj.style:这个方法只能JS只能获取写在html标签中的写在style属性 ...

  2. 深入理解DOM节点类型第七篇——文档节点DOCUMENT

    × 目录 [1]特征 [2]快捷访问 [3]文档写入 前面的话 文档节点document,隶属于表示浏览器的window对象,它表示网页页面,又被称为根节点.本文将详细介绍文档节点document的内 ...

  3. window.innerWidth、document.body.clientWidth和html的大小的区别

    首先,我们知道document.body指向的就是body元素,如此,我们就可以以document.body来获取body的大小.何以知之?如下代码: var body = document.quer ...

  4. DOM (Document Object Model)文档对象模型

    [理解下DOM] DOM——Document Object Mode.DOM是网页上XHTML中文档正文标题啊.段落.列表.样式.以及ID/class等所有其他数据的一个内部表示.我自己的理解是将网页 ...

  5. bug记录_document.defaultview.getcomputedstyle()

    页面中使用document.defaultview.getcomputedstyle()在火狐下取不到值. 原本方法现在$(document).ready()中,换到window.onload里就可以 ...

  6. jacascript document对象

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! Document 类型表示文档,或文档的根节点,这个节点是隐藏的,没有具体的节点标签:而 html 是根标 ...

  7. (87)Wangdao.com第二十天_JavaScript document 节点对象

    document 节点对象, 代表整个文档,每张网页都有自己的 document 对象. window.document 当浏览器开始加载文档时就存在了 正常的网页使用 document 或者 win ...

  8. 浏览器根对象document之字符串属性

    1.1 停止使用的属性 fgColor.linkColor.vlinkColor.alinkColor.bgColor. 1.2 文档地址 document.URL 与documentURI属性返回同 ...

  9. Window与Document

    Window 表示一个包含DOM文档的窗口,其 document 属性指向窗口中载入的 DOM文档.使用 document.defaultView 属性可以获取指定文档所在窗口.window作为全局变 ...

随机推荐

  1. Sublime text3 笔记

    打算换个编辑器,以前用dw,在到Aptana,都是比较大的编辑器了,打开的时候都有些慢,久闻sublime text3,小巧轻便,插件丰富,所以决定换下 官网下载地址(ps 之前下载了各种的破解版,总 ...

  2. Mysql部分常用类型长度含义

    Int:一个Int类型4字节                              在sql中长度为1则代表一个Int类型的长度          有符号区分的范围:2147483647~-214 ...

  3. 人情世故&潜规则

    大凡成功的牛人,无一例外都明白这一点.他们读懂了社会的本质和人际交往的潜规则,知道对方需要什么,知道对方脑子里在想什么.你几乎看不见他奔波劳碌,但是在不动声色中,他就已经实现人生目标.他们成功的密码是 ...

  4. CSS之transition(动画)

    Transform字面上就是变形,改变的意思.在CSS中transform主要包括以下几种:旋转rotate.扭曲skew.缩放scale和移动translate以及矩阵变形matrix. 下面我们一 ...

  5. 北大ACM(POJ1009-Edge Detection)

    Question:http://poj.org/problem?id=1009问题点:RLE编码. Memory: 648K Time: 547MS Language: C++ Result: Acc ...

  6. jquery对象与js对象的相互转换

    jQuery对象转成DOM对象: 两种转换方式将一个jQuery对象转换成DOM对象:[index]和.get(index); (1)jQuery对象是一个数据对象,可以通过[index]的方法,来得 ...

  7. lua中pairs和ipairs的区别

    标准库提供了集中迭代器,包括迭代文件每行的(io.lines),迭代table元素的(pairs),迭代数组元素的(ipairs),迭代字符串中单词的 (string.gmatch)等等.LUA手册中 ...

  8. WAS缓存导致修改文件不生效问题

    当用ftp上传部署增量文件,was应用不生效问题解决方法:一. 修改web.xml文件,需要修改以下三个目录下的文件:1. /opt/IBM/WebSphere/AppServer/profiles/ ...

  9. ubuntu下安装git,sublime,nodejs

    用的是VMware10.0版本的虚拟机,很早之前下载的今天就直接用了,安装挺简单记得需要一个序列号.在这里:http://mirrors.163.com/ubuntu-releases/15.04/u ...

  10. 反射-Reflect

    1.得到一份Class(同一个类在JVM中只有一份字节码) 三种方式:类名.class, Class.forName("全限定名");, 对象.getClass(); 基本类型 i ...