在准备状态之前操作dom是否可以?

时间:2009-08-03 15:01:34

标签: javascript dom progressive-enhancement domready

这通常是我如何管理渐进增强同时保持体验清洁,但它有多安全?是否存在竞争条件,这不起作用?

想象一下简单的抽象场景,如果你有javascript支持,你想要以不同的方式显示...这通常是我最终要做的事情:

<div id="test">original</div>
<script type="text/javascript">
    var t = document.getElementById('test');
    t.innerHTML = 'changed';
</script>

许多人可能声称你应该使用一个框架并等待一个domready事件,并在那里进行更改..但是有一个显着的延迟,其中'test'元素将在文档结束和css之前呈现准备就绪并且已经触发了......因此导致了“原始”的显着闪烁。

此代码是否容易出现竞争失败?或者我可以保证一个元素是可发现的并且如果它存在于脚本之前可以修改吗?

提前致谢。

5 个答案:

答案 0 :(得分:5)

你可以,但是有一些问题围绕这样做。

首先,在IE中,如果你试图操纵一个尚未关闭的节点(例如BODY在它的关闭标签之前应该在你的JS之下),那么你可能会遇到IE的“OPERATION ABORTED”错误,这将导致一个空白页。操作节点包括附加节点,移动节点等。

在其他浏览器中,行为是未定义的,但它们的行为通常与您期望的一样。主要问题是随着页面的发展,页面可能以不同方式加载/解析/运行。这可能会导致某些脚本在浏览器定义实际创建的引用元素并使其可用于DOM操作之前运行。

如果您试图提高用户感知性能(即快捷方式)。我强烈建议你避开这条路,并考虑减轻你的网页。您可以使用Yahoo的YSlow / Google的Page Performance Firebug来帮助您入门。

Google's Page Speed

Yahoo's YSlow

答案 1 :(得分:3)

您可以在DOM完全加载之前对其进行操作,但这可能存在风险。您显然无法保证您尝试操作的DOM的位实际存在,因此您的代码可能会间歇性地失败。

答案 2 :(得分:1)

只要您只修改脚本块之前的节点(即节点的结束标记位于脚本的开始标记之前),就不会遇到任何问题。

如果您想确保操作成功,请将代码包装在try...catch块中,并在失败时通过setTimeout()再次调用。

答案 3 :(得分:0)

在Viajeros.com我有一个装载指示器工作8-9个月,到目前为止我没有问题。它看起来像这样:

<body>

<script type="text/javascript">
    try {
        document.write('<div id="cargando"><p>Cargando...<\/p><\/div>');
        document.getElementById("cargando").style.display = "block";
    } catch(E) {};
</script>

答案 4 :(得分:-1)

过早地访问DOM会引发IE 5和Navigator 4中的异常。