是“onload”吗?当代码位于底部时有必要吗?

发布于 2024-12-24 19:05:25 字数 170 浏览 1 评论 0原文

我想知道 window.onload = function(){} (或任何其他类型的 onload,如 jQuery $(document).ready(); 是否必要如果代码放在我的 的底部?

或者可能会出现非常意外的副作用?

I was wondering if the window.onload = function(){} (or any other kind of onload, like the jQuery $(document).ready(); is necessary if the code is placed at the bottom of my <body>?

Or there could be highly unexpected side-effects?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怪我太投入 2024-12-31 19:05:25

是的,可能会出现意想不到的后果。但是,不,这不是绝对必要的。对于仍在加载的内容(例如复杂的布局、深层 DOM 结构、来自其他脚本的动态 HTML 或图像),时机可能已关闭。为了避免这些情况,将脚本包装在 onload 事件中始终是最安全的。

以下是一些例子来证明这一点。所有示例均在 OS X 上的 Chrome 17.0.963.12 开发版上进行测试。不使用 onload 时,浏览器结果可能会有所不同,这表明了其不可预测的行为。如果结果与您的预期(即您的设计指定的)不同,这些示例将返回 fail;当结果与您的预期相符时,这些示例将返回 success。使用onload,它们总是返回成功

示例 1

在此示例中,代码期望图像具有特定宽度。如果代码包含在 onload 事件中,则宽度是正确的,否则宽度是不正确的。

演示:http://jsfiddle.net/ThinkingStiff/qUWxX/

HTML:

<div id="result"></div>
<img id='image' src="http://thinkingstiff.com/images/matt.jpg" />

脚本:

document.getElementById( 'result' ).innerHTML 
    = document.getElementById( 'image' ).offsetWidth == 346 ? 'success': 'fail';

您会看到jsFiddle 设置为页面左上角的“onLoad”,图像上方的结果是成功

在此处输入图像描述

将其更改为“onDomReady”或“无换行(正文)”:

在此处输入图像描述在此处输入图像描述

现在按页面左上角的“运行”:

在此处输入图像描述

图像上方的结果现在将是 失败。

示例 2

这是另一个不使用图像的示例。在此示例中,内联脚本已添加到 HTML 中。该代码期望宽度是内联脚本设置的宽度。使用 onload 是正确的,不使用则不是。对于此演示,请使用与之前相同的说明。

演示: http://jsfiddle.net/ThinkingStiff/n7GWt/

HTML:

<div id="result"></div>
<div id="style"></div>

<script>
    window.setTimeout( function() { 
        document.getElementById( 'style' ).style.width = '100px'; 
    }, 1 );
</script>

脚本:

document.getElementById( 'result' ).innerHTML 
    = document.getElementById( 'style' ).style.width ? 'success' : 'fail';

示例 3

这是一个正文中不使用图像或 Javascript,仅使用 CSS 的示例。同样,onload 和 not 之间的结果是不同的。

演示: http://jsfiddle.net/ThinkingStiff/HN2bH/

CSS:

#style {
    animation:             style 5s infinite;
        -moz-animation:    style 5s infinite;
        -ms-animation:     style 5s infinite;
        -o-animation:      style 5s infinite;
        -webkit-animation: style 5s infinite;
    border: 1px solid black;
    height: 20px;
    width: 100px;    
}

@keyframes             style { 0% { width: 100px; } 100% { width: 500px; } }
    @-moz-keyframes    style { 0% { width: 100px; } 100% { width: 500px; } }
    @-ms-keyframes     style { 0% { width: 100px; } 100% { width: 500px; } }
    @-o-keyframes      style { 0% { width: 100px; } 100% { width: 500px; } }
    @-webkit-keyframes style { 0% { width: 100px; } 100% { width: 500px; } }

HTML:

<div id="result"></div>
<div id="style"></div>

脚本:

document.getElementById( 'result' ).innerHTML 
    = document.getElementById( 'style' ).clientWidth > 100 ? 'success' : 'fail';

有在很多情况下,不包装代码可能会导致您无法预料的问题。为了避免这些情况,将脚本包装在 onload 事件中始终是最安全的。

Yes, there could be unexpected consequences. But, no, it's not absolutely necessary. The timing could be off for things still loading, like complicated layouts, deep DOM structures, dynamic HTML from other scripts, or images. To avoid these situations, it's always safest to wrap your script in an onload event.

Here are some examples that demonstrate this. All examples tested on Chrome 17.0.963.12 dev on OS X. Browser results may vary when not using onload, which demonstrates its unpredictable behavior. The examples return fail if the result is different than what you'd expect (i.e. what your design specifies) and return success when the result matches what you would expect. With onload they always return success.

Example 1

In this example, the code is expecting the image to be a certain width. If the code is wrapped in an onload event the width is correct, otherwise, it's not.

Demo: http://jsfiddle.net/ThinkingStiff/qUWxX/

HTML:

<div id="result"></div>
<img id='image' src="http://thinkingstiff.com/images/matt.jpg" />

Script:

document.getElementById( 'result' ).innerHTML 
    = document.getElementById( 'image' ).offsetWidth == 346 ? 'success': 'fail';

You'll see the jsFiddle is set to "onLoad" in the upper left corner of the page and the result above the image is success.

enter image description here

Change that to "onDomReady" or "no wrap (body)":

enter image description hereenter image description here

Now press "Run" at the top left of the page:

enter image description here

The result above the image will now be fail.

Example 2

Here is another example that doesn't use images. In this one, an inline script has been added to the HTML. The code is expecting the width to be what it was set to by the inline script. With onload it's corrent, without, it's not. Use the same instructions as before for this demo.

Demo: http://jsfiddle.net/ThinkingStiff/n7GWt/

HTML:

<div id="result"></div>
<div id="style"></div>

<script>
    window.setTimeout( function() { 
        document.getElementById( 'style' ).style.width = '100px'; 
    }, 1 );
</script>

Script:

document.getElementById( 'result' ).innerHTML 
    = document.getElementById( 'style' ).style.width ? 'success' : 'fail';

Example 3

Here's an example that uses no images or Javascript in the body, just CSS. Again, the results are different between onload and not.

Demo: http://jsfiddle.net/ThinkingStiff/HN2bH/

CSS:

#style {
    animation:             style 5s infinite;
        -moz-animation:    style 5s infinite;
        -ms-animation:     style 5s infinite;
        -o-animation:      style 5s infinite;
        -webkit-animation: style 5s infinite;
    border: 1px solid black;
    height: 20px;
    width: 100px;    
}

@keyframes             style { 0% { width: 100px; } 100% { width: 500px; } }
    @-moz-keyframes    style { 0% { width: 100px; } 100% { width: 500px; } }
    @-ms-keyframes     style { 0% { width: 100px; } 100% { width: 500px; } }
    @-o-keyframes      style { 0% { width: 100px; } 100% { width: 500px; } }
    @-webkit-keyframes style { 0% { width: 100px; } 100% { width: 500px; } }

HTML:

<div id="result"></div>
<div id="style"></div>

Script:

document.getElementById( 'result' ).innerHTML 
    = document.getElementById( 'style' ).clientWidth > 100 ? 'success' : 'fail';

There are just too many scenarios where not wrapping your code can cause issues that you won't be able to anticipate. To avoid these situations, it's always safest to wrap your script in an onload event.

饭团 2024-12-31 19:05:25

发生了一些不同的事情。

  1. onload 仅在加载图像等嵌入内容后调用。这意味着您可以将代码放入 onload 中,具体取决于该内容。
  2. 当页面的 DOM(即内部结构)完全加载时,就绪处理程序会在此之前触发。这与将其放在底部没有什么不同,但一个区别是,如果有人离开您的页面然后返回,这些处理程序将再次触发。

从技术上讲,在文档末尾运行的脚本可以使用 getElementById 等方法来提取已呈现的元素。由于上述原因,您可能仍然希望将它们放入就绪或加载处理程序中。这并不是说脚本本身不应该位于底部 - 将它们放在底部仍然有利于感知性能。

Couple of different things going on.

  1. onload is called only after embedded content such as images is loaded. This means you can put code in onload that depends on that content being there.
  2. ready handlers are fired before that, when the DOM (ie internal structure) of your page is fully loaded. This isn't that different from putting it at the bottom, but one difference is that if someone navigates away from your page and then back, these handlers will fire again.

Technically scripts that run at the end of the document can use methods like getElementById to pull in elements that are already rendered. You may still want to put those in a ready or load handler for the above reasons. This isn't to say the scripts themselves shouldn't be at the bottom - there's still a benefit to perceived performance from having them there.

唐婉 2024-12-31 19:05:25

HTML 页面底部的脚本标记相当于 DOMContentLoaded。所有 html 代码都已下载,Javascript 现在可以访问 DOM 元素了。

当所有其他资源(例如图像)完全下载时调用 load

A script tag at the bottom of an HTML page is equivalent to DOMContentLoaded. All the html code has been downloaded, and Javascript is now capable of accessing DOM elements.

load is called when all other resources, such as images, have completely downloaded.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文