我可以在加载整个页面之前运行 javascript 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2920129/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:29:28  来源:igfitidea点击:

Can I run javascript before the whole page is loaded?

javascripthtml

提问by picknick

I want to run a bit of javascript before the whole page has loaded. Is this possible? Or does the code start to execute on </html>?

我想在整个页面加载之前运行一些 javascript。这可能吗?还是代码开始执行</html>

回答by T.J. Crowder

Not only canyou, but you have to make a special effort notto if you don't want to. :-)

你不仅可以,而且如果你不想,你必须特别努力不要。:-)

When the browser encounters a scripttag when parsing the HTML, it stops parsing and hands over to the Javascript interpreter, which runs the script. The parser doesn't continue until the script execution is complete (because the script might do document.writecalls to output markup that the parser should handle). This is the default behavior; there are scripttag attributes that change that behavior (deferand async) (and because they change it, scripts loaded with deferor asynccannot use document.writeto output HTML to the page being loaded).

当浏览器script在解析 HTML 时遇到标签时,它会停止解析并移交给运行脚本的 Javascript 解释器。解析器在脚本执行完成之前不会继续(因为脚本可能会document.write调用解析器应该处理的输出标记)。这是默认行为;有一些script标记属性会改变这种行为(deferasync)(并且因为它们改变了行为,加载的脚本deferasync不能用来document.write将 HTML 输出到正在加载的页面)。

So consider this:

所以考虑一下:

<p>Line 1</p>
<script>
    alert("Paragraphs: " + document.getElementsByTagName("p").length);
</script>
<p>Line 2</p>

If you load that page, the alert will show "Paragraphs: 1" because only one pelement exists in the DOM at that point (the one containing "Line 1"). You may or may not see Line 1 in the browser display, depending on the browser, because even though the element is in the DOM, the browser may not have had time to renderit yet (since alertbrings the UI thread to screeching halt).

如果您加载该页面,警报将显示“段落:1”,因为p此时 DOM 中仅存在一个元素(包含“第 1 行”的元素)。您可能会也可能不会在浏览器显示中看到第 1 行,这取决于浏览器,因为即使元素在 DOM 中,浏览器也可能没有时间渲染它(因为alertUI 线程会突然停止)。

Some browsers are...adjusting...the behavior of alert, though. For instance, if you had that code in a page and opened it in a new tab in the background, recent versions of Chrome would allow the page to continue loading (and allow JavaScript code to keep running), and show the alert when you went to the tab, even though that's very different to the behavior when you encounter that alert when the tab is active.

不过,有些浏览器正在……调整……的行为alert。例如,如果您在一个页面中拥有该代码并在后台的新选项卡中打开它,则最新版本的 Chrome 将允许该页面继续加载(并允许 JavaScript 代码继续运行),并在您访问时显示警报到选项卡,即使这与您在选项卡处于活动状态时遇到该警报时的行为非常不同。

Whether they've been rendered or not, you can happily access the earlier elements, which is why we saw "Paragraphs: 1" above. Here's another example:

无论它们是否已被渲染,您都可以愉快地访问较早的元素,这就是我们在上面看到“段落:1”的原因。这是另一个例子:

<p id='p1'>Line 1</p>
<script>
    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 2</p>

The output you see is:

你看到的输出是:

Line 1
p1 is null? no
p2 is null? yes
Line 2

...because p1exists as of when the script runs, but p2doesn't.

...因为p1脚本运行时存在,但p2不存在。

I don't have a link handy, butIn this message, the developers of the Google Closure library say that they don't see any big value to the "ready" style events that Prototype, jQuery, ExtJS, Dojo, and most others provide because if you put the script after the elements you want to interact with, you're fine; which falls in line with YUI's recommendationthat you just put your scripts right before the closing </html>tag (since you have to put them somewhere, after all, and down there they don't hold up your page display). Now, personally, I do see some value in those events although I think they're over-used, but my point is that clearly you can start interacting with things very early on.

我手边没有链接,但在此消息中,Google Closure 库的开发人员表示,他们认为 Prototype、jQuery、ExtJS、Dojo 和大多数其他类型的“就绪”样式事件没有任何大的价值提供是因为如果您将脚本放在要与之交互的元素之后,那就没问题了;这符合YUI 的建议,即您只需将脚本放在结束</html>标记之前(毕竟您必须将它们放在某个地方,而在那里它们不会阻止您的页面显示)。现在,就我个人而言,我确实看到了这些事件的一些价值,尽管我认为它们被过度使用了,但我的观点是很明显你可以很早就开始与事物进行交互。

回答by Marian

You can run javascript code at any time. AFAIK it is executed at the moment the browser reaches the <script> tag where it is in. But you cannot access elements that are not loaded yet.

您可以随时运行 javascript 代码。AFAIK 它是在浏览器到达它所在的 <script> 标记的那一刻执行的。但是您无法访问尚未加载的元素。

So if you need access to elements, you should wait until the DOM is loaded (this does not mean the whole page is loaded, including images and stuff. It's only the structure of the document, which is loaded much earlier, so you usually won't notice a delay), using the DOMContentLoadedevent or functions like $.readyin jQuery.

所以如果你需要访问元素,你应该等到 DOM 被加载(这并不意味着整个页面都被加载,包括图像和东西。它只是文档的结构,它加载得更早,所以你通常会赢没有注意到延迟),使用jQuery 中的DOMContentLoaded事件或函数$.ready