为什么window.onload事件会在$(document).ready之前发生?

14
根据这个线程所述:window.onload vs $(document).ready()window.onload 应该比 $(document).ready() 发生得更晚,但在这段简单的代码中,日志将显示 onload 事件在 ready 事件之前执行?我错过了什么吗?

<!DOCTYPE html>
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>

<body>
  <h1>A Simple Site</h1>
  <script>
    $(document).ready(function() {
      console.log("ready event fired");
    })
     window.onload = function() {
      console.log("onload event fired");
    }
  </script>
</body>

</html>


4
您的页面中没有任何内容会影响加载事件(例如外部CSS或图像),因此load事件几乎立即触发。我想它会比jQuery的document.ready事件更早触发,因为jQuery本身有些开销。如果您在HTML中添加一个img元素,则ready处理程序将首先触发-这是您期望的行为。 - Rory McCrossan
@BharatPatidar 这就是问题所在,OP在他们的问题中链接了一个声明行为应该与OP得到的相反 - 这也是这个问题的重点。 - Rory McCrossan
@RoryMcCrossan 是的,同意你的第一条评论。 - Bharat
@RoryMcCrossan 我刚试图将不同的图片添加到代码中。似乎我必须添加一定数量的图片才能在稍后发生onload事件,这对我来说很奇怪。因为即使只有一张图片,onload事件也必须等待更长时间才能加载该图片,因此会稍后发生。 - Hoang Vu
3个回答

16

问题并不在于事件的顺序,而是由于jQuery包装了本地DOM事件。如果您尝试使用本地的DOMContentLoaded,您会发现它始终在window.onload之前运行。但是,jQuery事件$(document).ready将在DOMContentLoaded之后一些毫秒执行,这在某些情况下可能会在window.onload之后出现,特别是如果页面没有太多需要加载的内容,如下面的代码所示。这种延迟是由于jQuery实现造成的。

如果您取消代码中的iframe注释,则需要一些时间来加载,这会导致window.onload被延迟,因此$(document).ready将首先执行。

<!DOCTYPE html>
<html>

<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>

<body>
    <h1>A Simple Site</h1>
    <!-- <iframe src="http://stackoverflow.com"></iframe> -->
    <script>
        $(document).ready(function() {
            console.log("jQuery ready");
        })
        
        document.addEventListener("DOMContentLoaded", function(event) {
            console.log("DOM ready");
        });
        
        window.onload = function() {
            console.log("DOM loaded");
        }
    </script>
</body>
</html>


4
这是jQuery 3的一个“特性”。jQuery 1.X版本始终在$(window).on('load')之前处理$(document).ready。此外,可以将$(window).load()视为页面呈现时的事件。我对此非常确定,因为我刚刚尝试将jQuery版本升级到3.X,并且这个项目使用了近10年的jQuery 1.X,但这次尝试导致了一个月的头疼,因为需要处理$(document).ready和$(window).load。最终决定使用jQuery 1.12.4,这是1.X系列的最新版本。

1

@RoryMcCrossan说得对,你的html中没有任何需要在window上加载的内容(如图像、视频等)。现在你可以看到事件行为如何改变了。

<!DOCTYPE html>
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
   <img src="http://www.wallpapereast.com/static/images/Unique-And-Beautiful-Wallpaper-HD.jpg" alt="Alternate Text" />

  
</head>

<body>
  <h1>A Simple Site</h1>
  <script>
    $(document).ready(function() {
      console.log("ready event fired");
    })
     window.onload = function() {
      console.log("onload event fired");
    }
  </script>
</body>

</html>


我刚试了一下你的代码。如果我只加载第一张图片,行为仍然不符合预期。你有什么解释吗? - Hoang Vu
@HoangVu 现在你可以看到只有一张图片,onload事件在ready之后触发,你可以理解我的意思。由于图像大小较小,所以它不需要比DOM准备好所需的时间更长。 - Bharat
@BharatPatridar 我可以看出图片的大小/数量很重要,但这是否意味着 onload 事件不需要等待 DOM 完全加载,或者 ready 事件等待比没有图片更多的内容? - Hoang Vu
如果没有类似于(CSS,图像)的东西,则“onload”不关心DOM是否准备就绪,而DOM也不会等待图像完全加载。 - Bharat
1
抱歉,我不认为这是正确的,因为在页面完全加载之前DOM已经准备好了 链接DOMContentLoaded事件也总是在onload事件之前触发,无论图像是否存在。因此,我的结论是jQuery的$(document).ready不仅等待DOM准备就绪,还等待其他内容。而jQuery的ready事件相对于window.onload何时触发仍然是我的问题。 - Hoang Vu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接