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. Miniui updateRow更改列字段值

    当UPC等于upccode时,更改列Scanned+1 //先grid.findRow找到UPC等于upccode的行对象 var row = grid.findRow(function (row) ...

  2. JSCharts

    JsCharts是一款轻量级的,基于js的图形报表工具,提供了线形图,柱状图,饼图,使用简单,相对其他的图表如FusionCharts来讲功能可能不是特别强大,但是对于一些要求不高的应用来讲已经够用了 ...

  3. Linux 基本命令学习笔记

    1. 文件管理 Ø touch  新建文件.例: touch test.txt  新建一个test.txt 文件. Ø cp 复制文件.例:cp ./user_one/test_one  ./user ...

  4. web HTML5 调用摄像头的代码

    最近公司要求做一个在线拍照的功能,具体代码如下: <html> <head> <title>html5调用摄像头拍照</title> <style ...

  5. AMQ学习笔记 - 12. Spring-JmsTemplate特性设置

    概述 这是关于JmsTemplate的最后一篇总结,且只会介绍几个比较重要的特性. 消息的递送模式 在发送消息给时,可以告知这是持久化的消息,还是非持久化的消息.如果是非持久化的消息,broker会将 ...

  6. 《JavaScript高级程序设计》心得笔记-----第四篇章

    第十六章 1.  跨文档消息传送: postMessage("消息", "发送消息的文档所在域") 2.  拖放事件: 1)   拖动某元素会依次触发:drag ...

  7. ADO.NET笔记——使用DataSet返回数据

    相关知识: DataSet和DataAdapter的内部结构: DataSet通过DataAdapter从数据库中获取数据 DataSet对象内部包括一个集合(Tables),也就是可以拥有多个表(D ...

  8. Xcode中为代码添加特殊标记

    有时候,我们需要在代码中搜索特殊的符号或者代码段,根据符号或使用搜索功能导航代码段效率并不算高.为了使用普通的英语标识重要的代码片段,可在代码中插入特殊格式的注释.这些注释不会在应用程序中添加任何特殊 ...

  9. 方便实用的jQuery checkbox复选框全选功能

    // 主复选框 <input type="checkbox" id="ck" name="ckAll">// 子复选框项 < ...

  10. 批处理测试局域网网络连通性ping1-255

    for /l %%1 in (1 1 255)do ping /n 1 192.168.1.%%1       ##bat下 运行 for /l %i in (1,1,254) do ping -n ...