检查 DOM 的准备情况是不是矫枉过正?

Posted

技术标签:

【中文标题】检查 DOM 的准备情况是不是矫枉过正?【英文标题】:Is checking for the readiness of the DOM overkill?检查 DOM 的准备情况是否矫枉过正? 【发布时间】:2010-11-25 18:32:41 【问题描述】:

我正在开发一个使用网络技术开发桌面应用程序的平台。在这样做的过程中,我一直在尝试让一些文档/就绪功能与我将集成到平台中的浏览器一起使用。这就是为什么我之前在 SO 上问过这个问题:javascript-framework-that-primarily-provides-just-document-onready-functionality

但是,我无法让我选择的浏览器(嘘,这是一个秘密;)来成功利用该浏览器建议的功能,并且只能回答上述问题。所以,在试图弄清楚什么可能有效的过程中,我偶然发现了以下内容。

下面的代码在我正在使用的浏览器中具有相同的效果,只需在 1 毫秒超时后执行一个函数即可:我可以在加载大图像时写入 DOM。这对我来说可能不是最终的解决方案,我可能会写一些特定于这个浏览器的 Javascript 引擎如何实现 DOM 功能的东西。

尽管如此,我还是决定看看这是否适用于标准浏览器,令我惊讶的是,它确实有效!鉴于此,我的问题是:各种 Javascript 框架提供的 dom/readiness 功能的各种实现,是否只是矫枉过正?

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script>
setTimeout(function() 
    var txtNode = document.createTextNode("ready_yet?");
    var ready_yet_el = document.getElementById("ready_yet");
    ready_yet_el.appendChild(txtNode);
,1);
</script>
</head>

<body>
<div id="ready_yet"></div>
<img src="http://www.ryanmorr.com/tests/ondomready/pic.jpg" />
</body>

</html>

编辑/进一步的想法 在the page linked to by the answer to my previous related question 上,它声明“对于 Firefox 和 Opera,只需简单检查事件类型即可确定它是否为 DOMContentLoaded。Safari 和 IE 将检查文档的就绪状态...。最后,万一一切都失败了,onload 事件将带来在后面。”也许类似于我上面的 setTimeout 的 setInterval 可能是倒数第二个行动方案,然后才将 onload 作为最后的手段?无论如何,使用我选择的可嵌入浏览器,似乎既不支持 DOMContentLoaded 事件,也不支持 document.readyState。

【问题讨论】:

您的示例有效,因为(您可能知道)在 div 被解析后调用超时函数,一个更简单的版本是让脚本在 div 之后运行(没有超时)已关闭,不是规范,但所有浏览器都会在继续解析 xml/html 节点之前使 dom 节点可用(或至少在下一个 dom 元素被完全读取和执行之前可用)。 我认为您在前 3 小时内得到的答案只阅读了问题的标题。他们都说“不,在 DOM 准备好之前运行脚本很糟糕”。 我预计会受到更严厉的对待 ;) 但要确认我的直觉,即使有参考资料显示其他人“打败了我”,这正是我所寻找的,并且让我以一定的信心继续沿着这条道路前进;接下来我将看看 Peppy 或 Sizzle 等 CSS 选择框架是否适用于这个特定的浏览器实现。 【参考方案1】:

您的预感很好,并且有充分的依据 IMO。但是someone has beat you to the punch already。简短的回答是setTimeout 不是在所有情况下检测 DOM 就绪的工作实现。您感兴趣的浏览器可能没问题,但 IE 在某些情况下会失败。

您可能感兴趣的是,Microsoft 自己的 ASP.NET AJAX 框架使用setTimeout 技巧来检测 DOM 准备情况。惊喜,惊喜:it fails in certain use cases as well。

简而言之,问题似乎在于加载脚本缓慢的 IE,这可能是由于文件大小过大(例如 ~500K)或网络/服务器延迟所致。

【讨论】:

【参考方案2】:

不,因为当 DOM“未就绪”错误出现时,它们会以非常不寻常且难以预测和追踪的方式出现 - 每个(当然)对于它发生的浏览器来说都是独一无二的。

完全避免这些问题并知道您将始终处理准备好的 DOM 会容易得多。

例如,不久前,我在每个人最喜欢的浏览器中遇到了一个 DOM 未就绪的错误,它通过 99% 的时间完美地表现出来,但如果页面内容中有一个带有 src 属性的 img 元素,则会因错误而死并且如果内容也有一个 ul 元素,其中包含任意数量的 li...

我很容易说现在“哦,这是一个 DOM 问题”,但当时......不,不是那么容易。

【讨论】:

【参考方案3】:

简单地说,不。连接速度较慢且要加载多个文件的人不会喜欢他们的浏览器尝试在尚不存在的元素上运行脚本。

【讨论】:

以上是关于检查 DOM 的准备情况是不是矫枉过正?的主要内容,如果未能解决你的问题,请参考以下文章

检查是不是在没有 DOM 对象的情况下单击了“a”链接

使用 boto3 检查 s3 的存储桶中是不是存在密钥

检查 DOM 元素是不是可以交互

检查是不是可以与 DOM 元素交互

如何在没有 API 8 中引入的 onLoadCompleteListener 的情况下检查 SoundPool 是不是准备好播放?

如何使用反应酶检查实际的 DOM 节点