【问题标题】:Is window.document ever null or undefined?window.document 是否曾经为空或未定义?
【发布时间】:2012-08-20 13:59:20
【问题描述】:

我一直在对 window.document 对象进行一些研究,以确保我的 JavaScript 解决方案之一是可靠的。是否存在 window.document 对象为 null 或未定义的情况?

为了便于讨论,这里有一段不相关的示例代码。是否有任何情况下这段代码会失败(也就是抛出异常)?

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

【问题讨论】:

  • 您是在问决定是否需要检查一下吗?我不想考虑不得不到处写“if(window && window.document && window.document. ...) {”。
  • 绝对!期待它被定义就好了。
  • 您应该对使用文档对象的上下文有足够的了解,以了解它是否可以为空,以及如何适当地处理它。您的验证必须以上下文为条件。否则,每次使用它时,您总是会测试每个变量是否为 null。我们不会那样写代码。在您的示例中,如果没有引用真实的窗口,则测试就绪状态的上下文将没有意义。

标签: javascript dom


【解决方案1】:

是否存在 window.document 对象为 null 或未定义的情况?

是的,对于不在文档中的 JavaScript 代码(例如 node.js)。但是这样的代码也可能没有窗口对象(尽管它会有一个全局对象)。

对于符合 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 就绪功能失败(可能至少在某些浏览器中,但不是桌面和某些移动设备流行使用的浏览器),
  2. 没有window object,或者
  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
  • @OmarTariq——谁喜欢?如果全局空间中的 this 没有引用全局对象,则实现与 ECMA-262 不一致,所有赌注都关闭。在那种情况下,伪造对 eval 的间接调用有什么意义呢?您或任何人是否确定了 global this 不是全局对象但 eval('this') 是的实现?
【解决方案2】:

我认为文档总是被定义的,因为浏览器向您显示的所有内容都是 html 文档,甚至是 site is not available 。另外,document 是只读属性

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

【讨论】:

    【解决方案3】:

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

    可能还有一些关于“页面加载”是什么意思的问题。您是否正在尝试查看 DOM 是否已呈现并且元素是否已准备好进行操作?或者您是否正在检查页面加载是否确实完成,其中包括加载所有其他元素,例如图形。

    这个讨论可能有用: How to check if DOM is ready without a framework?

    【讨论】:

    • 本质上,我所做的最终目标是找到一种可靠的方法来确定页面是否已加载。如果页面立即加载(通过 onload 检测)或动态加载(您错过了 onload 事件),基本上找到一个可行的解决方案。
    • @N. Taylor Mullen 我认为这是可靠的方法,因为这是在DOM level 1 中定义的。可能只在一些古老的移动浏览器上不是
    • 你会感到惊讶 =)。在 IE8 及更低版本以及所有版本的 Opera 中,PageLoaded 在我的示例中都是正确的,即使它只是在 DOM 加载后触发^^。
    • @N. Taylor Mullen,谢谢你的想法,但是请编辑你的问题,因为它是关于 window.document undefined 并且你需要 readyState 的可靠性
    • 就绪状态本身直接依赖于 windows.document 对象。我已经验证了 readyState 对象的可靠性,所以我现在正在努力验证 windows.document 对象。
    【解决方案4】:

    因为你的javascript代码必须写在html文档中,所以你的代码不能在文档外执行,换句话说,没有文档,没有javascript。

    【讨论】:

    • Javascript 不必在 HTML 文档中,宿主环境不限于文档甚至浏览器。
    • 但如果它不在 HTML 文档中,那么测试 document.readyState 将是荒谬的,而且你会遇到比让窗口为 null 更大的问题。
    • 问题是曾经有一个案例。没有什么可以说用户代理必须提供窗口或文档对象,并且网页的作者不知道哪些用户代理可以访问他们的页面。测试支持而不是运行会失败的代码而不是不采取任何预防措施而让它失败似乎是明智的。
    • 一个非常常见的反例是 NodeJS
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-13
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 2012-03-15
    • 2014-10-21
    相关资源
    最近更新 更多