window.document是否可能为null或undefined?

8

我一直在研究 window.document 对象,以确保我 JavaScript 解决方案的可靠性。是否存在 window.document 对象为 null 或 undefined 的情况?

为了讨论,这里提供一个与主题无关的代码示例。是否存在任何情况会导致这段代码失败(即抛出异常)?

$(document).ready(function() {
    var PageLoaded = (window.document.readyState === "complete");
});

1
你是在询问是否需要检查它来确定吗?我不想考虑到处都要写上 "if(window && window.document && window.document. ...) {" 这样的代码。 - dkretz
当然可以!期望它已经被定义会很好。 - N. Taylor Mullen
你应该了解在使用文档对象的上下文中足够的信息,以知道它是否可能为空,并且如何适当地处理它。你的验证必须受到上下文的限制。否则,每次使用变量时都要测试每个变量是否为空,这样写代码是不可取的。在你的例子中,如果没有真正的窗口被引用,测试准备状态的上下文就没有意义。 - dkretz
4个回答

5

在什么情况下window.document对象会是null或undefined?

在JavaScript代码不在文档中时(例如node.js),是可能出现的情况。但这种代码可能没有window对象(尽管它将拥有全局对象)。

对于符合W3C DOM标准的用户代理中的HTML文档,不会出现这种情况。

> Are there any situations in which this piece of code will fail (i.e. throw
> an exception)?
> 
> [snip jQuery code]

以下情况会导致代码出现问题:

  1. jQuery ready函数失败(在至少某些浏览器中可能会发生,尽管不会发生在流行的桌面和某些移动设备使用的浏览器中);
  2. 没有window对象;或者
  3. 没有window.document对象。

为了确保代码能够在各种主机上正常运行,您可以采取以下措施:

  if (typeof window != 'undefined' && window.document &&
      window.document.readyState == whatever) {
      // do stuff
  }

这并不需要花费太多额外的时间,可能只需要一次性完成。

其他选择:

(function (global) {
  var window = global;
  if (window.document && window.document.readyState == whatever) {
    // do stuff
  }
}(this));

并且

(function (global) {
  var window = global;

  function checkState() {
    if (window.document && window.document.readyState) {
      alert(window.document.readyState);
    } else {
      // analyse environment 
    }
  }
  // trivial use for demonstration
  checkState();
  setTimeout(checkState, 1000);
}(this));

获取全局的首选方式是使用(1, eval)("this")而不仅仅是this - Omar Tariq
@OmarTariq——被谁偏爱?如果全局空间中的this没有引用全局对象,那么实现就不符合ECMA-262标准,所有的赌注都是无效的。在这种情况下,伪造对eval的间接调用有什么意义呢?你或者其他人是否已经确定了一个全局this不是全局对象但eval('this')是的实现? - RobG

1

我认为文档始终被定义,因为浏览器显示给你的所有内容都是 HTML 文档,即使是"网站不可用"。此外,document 是只读属性。

window.document = null; 
console.log(window.document); //Document some.html#

1

忽略JavaScript在Web浏览器/用户代理以外的其他地方运行的事实,您的pageLoaded测试可能会在iframes上失败(未经测试,但我知道它们会变得奇怪)。

还有一些关于“页面加载完成”的含义的疑问。您是要查看DOM是否已呈现并准备好进行操作?还是要检查页面加载是否确实完成,其中包括所有其他元素(例如图形)也已加载。

这个讨论可能会有所帮助: 如何在没有框架的情况下检查DOM是否准备就绪?


本质上,我所做的最终目标是找到一种可靠的方法来确定页面是否已加载。基本上需要找到一种既能在页面立即加载时(通过onload事件检测),又能在动态加载时(可能会错过onload事件)正常工作的解决方案。 - N. Taylor Mullen
@N. Taylor Mullen 我认为这是可靠的方式,因为据我所知,这是在 DOM level 1 中定义的。只有一些古老的移动浏览器可能不支持。 - Dmitry Koroliov
你会感到惊讶的 =)。在IE8及以下版本以及所有版本的Opera中,在DOM加载后才触发PageLoaded事件,但在我的示例中却为true。^^ - N. Taylor Mullen
@N. Taylor Mullen,感谢您的提醒,但请编辑您的问题,因为它涉及到window.document未定义,并且您需要readyState的可靠性。 - Dmitry Koroliov
读取状态本身直接依赖于windows.document对象。我已经验证了readyState对象的可靠性,现在我正在追求验证windows.document对象。 - N. Taylor Mullen
但是如果没有文档对象和窗口对象,你就没有一个readyState;所以你不能说它比它们更可靠。如果这是要在浏览器中运行的代码(在外面测试没有意义),那么就有一个窗口。 - dkretz

0

由于您的 JavaScript 代码必须编写在 HTML 文档中,因此您的代码无法在文档外执行,换句话说,没有文档就没有 JavaScript。


4
JavaScript不必在HTML文档中,宿主环境不仅限于文档甚至浏览器。 - RobG
但如果它不在HTML文档中,那么测试document.readyState就没有意义了,你会有比窗口为空更大的问题。 - dkretz
问题是“是否曾经有这样的情况”。没有任何说明用户代理必须提供窗口或文档对象,网页作者也不知道用户代理可能访问他们的页面。检测支持并不运行将失败的代码似乎是明智的做法,而不是没有采取任何预防措施就让它失败。 - RobG
一个非常常见的反例是NodeJS。 - John Haugeland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接