10

这通常是我在保持体验干净的同时管理渐进增强的方式,但它有多安全?是否有可能出现竞争条件而这不起作用?

想象一下简单的抽象场景,如果你有 javascript 支持,你想显示不同的东西。这通常是我最终会做的事情:

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

许多人可能会声称您应该使用框架并等待 domready 事件,并在那里进行更改。但是在文档结束之前已经呈现“测试”元素并且 css 已准备好并且domready 触发.. 从而导致“原始”的明显闪烁。

此代码是否容易出现竞争条件失败?或者我可以保证一个元素在脚本之前存在的话是可发现和可修改的?

提前致谢。

4

5 回答 5

5

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

首先,在 IE 中,如果您尝试操作尚未关闭的节点(例如,在其关闭标记之前的 BODY,应该在您的 JS 下方),那么您可能会遇到 IE 的“OPERATION ABORTED”错误,这将导致空白页面。节点的操作包括追加节点、移动节点等。

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

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

谷歌的页面速度

雅虎的 YSlow

于 2009-08-03T15:22:15.407 回答
3

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

于 2009-08-03T15:06:30.340 回答
1

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

如果要确保操作成功,请将代码包装在一个块中,然后通过失败try...catch时再次调用它。setTimeout()

于 2009-08-03T15:29:20.683 回答
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>
于 2009-08-03T16:27:04.223 回答
-1

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

于 2012-06-22T07:33:51.657 回答