我想在整个页面加载之前运行一些javascript。这可能吗?或者代码是否开始在</html>
执行?
答案 0 :(得分:159)
不仅可以你,但如果你不愿意,你必须特别努力而不是。 : - )
当浏览器在解析HTML时遇到script
标记时,它会停止解析并移交给运行脚本的Javascript解释器。在脚本执行完成之前,解析器不会继续(因为脚本可能会对解析器应处理的输出标记执行document.write
次调用)。这是默认行为;有script
个标记属性可以更改该行为(defer
and async
)(因为它们会更改它,加载defer
或async
的脚本无法使用document.write
输出正在加载的页面的HTML。)
所以考虑一下:
<p>Line 1</p>
<script type='text/javascript'>
alert("Paragraphs: " + document.getElementsByTagName("p").length);
</script>
<p>Line two</p>
如果您加载该页面,则警报将显示“Paragraphs:1”,因为此时DOM中只存在一个p
元素(包含“Line 1”的元素)。您可能会或可能不会在浏览器显示中看到第1行,具体取决于浏览器,因为即使该元素位于DOM中,浏览器也可能没有时间呈现它(因为{{ 1}}使UI线程停止screeching。)
有些浏览器是...... 正在调整 ...... alert
的行为。例如,如果您在页面中包含该代码并在后台的新标签中将其打开,则最新版本的Chrome将允许该页面继续加载(并允许JavaScript代码继续运行),并在您去的时候显示警告到选项卡,即使这与当选项卡处于活动状态时遇到该警报时的行为非常不同。
无论它们是否已被渲染,您都可以愉快地访问早期元素,这就是我们在上面看到“Paragraphs:1”的原因。这是另一个例子:
alert
您看到的输出是:
Line 1 p1 is null? false p2 is null? true Line 2
...因为<p id='p1'>Line 1</p>
<script type='text/javascript'>
document.write("<p>p1 is null? " + (document.getElementById('p1') == null ? "yes" : "no") + "</p>");
document.write("<p>p2 is null? " + (document.getElementById('p2') == null ? "yes" : "no") + "</p>");
</script>
<p id='p2'>Line two</p>
在脚本运行时存在,但p1
没有。
我没有方便的链接,但是 In this message,Google Closure库的开发人员说他们没有看到“准备好”风格事件的任何重大价值Prototype,jQuery,ExtJS,Dojo和其他大多数人提供的,因为如果你把脚本放在你想要与之交互的元素之后,你就没事了;与YUI's recommendation一致,你只是把你的脚本放在收尾p2
标签之前(因为你必须把它们放在某处,毕竟,在那里他们不要不要抬起你的页面显示。现在,就个人而言,我确实看到了这些事件的一些价值,虽然我认为它们已被过度使用,但我的观点是,显然你可以很早就开始与事物进行互动。
答案 1 :(得分:6)
您可以随时运行JavaScript代码。 AFAIK是在浏览器到达&lt; script&gt;时执行的。标记它所在的位置。但是您无法访问尚未加载的元素。
因此,如果你需要访问元素,你应该等到DOM被加载(这并不意味着整个页面被加载,包括图像和东西。它只是文档的结构,它加载得更早,所以您通常不会注意到延迟),使用DOMContentLoaded
事件或jQuery中的$.ready
等函数。