【问题标题】:An event when document stops loading文档停止加载时的事件
【发布时间】:2012-05-04 04:57:00
【问题描述】:

我有一个网页,它的大部分内容都是在前端用 javascript 构建的。当基本的 HTML 被解析并构建了 DOM 树时,“ready”事件就会触发。在此事件中,将启动一个 javascript 代码,该代码会继续构建网页。

$().ready(function() {
    $(document.body).html('<img src = "img.png" />');
    $.ajax({
        url: 'text.txt'
    });
});

正如你在这个小例子中看到的,

  • 新元素被添加到 DOM
  • 更多内容,例如正在加载图片
  • ajax 请求正在发送中

只有当所有这些都完成时,当浏览器的加载进度条第一次消失时,我才认为我的文档实际上已经准备好了。有没有合理的方法来处理这个事件?

注意这个

$().ready(function() {
    $(document.body).html('<img src = "img.png" />');
    $.ajax({
        url: 'text.txt'
    });
    alert('Document constructed!');
});

还不够,因为 HTTP 请求是异步的。也许将处理程序附加到每个请求,然后检查所有请求是否都已完成是我想做的一种方法,但我正在寻找更优雅的东西。

附录: 我正在寻找的事件的更正式定义:

文档准备就绪且页面动态内容首次完成加载/执行时的事件,除非用户通过鼠标移动、点击等触发另一个事件。

【问题讨论】:

  • 浏览器如何知道你已经调用了 AJAX 而不是呢?它没有!这是您必须在应用程序中处理的事情。
  • 好吧,浏览器肯定知道动态内容何时第一次停止执行,因为进度条随即消失。但请注意,我不希望浏览器在 API 中公开这样的事件。但我正在寻找一个优雅的应用程序解决方案,如果有人听说过的话。
  • 好吧,我必须删除我的答案,因为现在我完全不理解你想要什么了。
  • P.S.不要使用$().ready(function(){,使用$(document).ready(function(){ 或更好$(function(){ api.jquery.com/ready
  • @Rocket 啊,谢谢。 ready 事件显然与任何实际元素无关,所以我认为没有理由在其中放置一个 :) 不知道不推荐。

标签: javascript jquery javascript-events


【解决方案1】:

here 所述,您可以在单个图像最终加载时注册加载事件。但是,正如那里所描述的那样,这可能在浏览器之间不可靠,或者如果图像已经在浏览器的缓存中。所以我认为至少其中一部分不是 100% 值得信赖的。话虽如此,您可以轻松地挂钩到一堆不同的异步事件,然后仅在所有事件都完成时才做出反应。例如:

$(document.body).html('<img src="img.png" id="porcupine"/>');

var ajaxPromise1 = $.get(...);
var ajaxPromise2 = $.get(...);
var imgLoadDeferred1 = $.Deferred();

$("#porcupine").load(
  function() {
    imgLoadDeferred1.resolve();
  }
);

$.when(ajaxPromise1, ajaxPromise2, imgLoadDeferred1).done(
  function () {
    console.log("Everything's done.");
  }
);

如果您想考虑到图像加载可能永远不会生成事件,您还可以设置一个计时器,该计时器最终会关闭并尝试解决尚未解决的 imgLoadDeferred1。这样您就不会被困在等待从未发生的事件。

【讨论】:

  • load 可能不是绝对值得信赖的,但是像这样的跨浏览器的东西很少。无论如何,您的代码似乎解决了我的问题。感谢您的完整回答:)
【解决方案2】:

您正在寻找.ajaxStop()

这样使用:

$("#loading").ajaxStop(function(){
      $(this).hide();
});

除非你想像上面的例子那样使用this,否则你附加到什么DOM元素并不重要。

来源:http://api.jquery.com/ajaxStop/

【讨论】:

  • 所以jQuery已经基本实现了传出请求计数器。但这是否仅适用于 jQuery 发出的 AJAX 请求?我在我的代码中使用了更多的框架。此外,这仍然不包括对图像的请求。但是谢谢你的信息,+1。
  • 确实适用于由jQuery发出的AJAX请求。
【解决方案3】:

将全局计数器添加到 ajax 调用,这样当 ajax 请求准备好时,它会调用 addToReadyCounter(); 函数,该函数将为 glogal var readyCount; +1。

在同一个函数中检查你的 readyCount 和触发事件处理程序

var readyCount = 0, ajaxRequestCount = 5;
function addToReadyCount() {
    ++readyCount;
    if (readyCount >= ajaxRequestCount) {
        documentReadyEvent();
    }
}

$.ajax(
...
    success: function(data){
        addToReadyCount();
}
...);

如果您仅使用 success: ... 进行 addToReaadyCount documentReadyEvent() 仅在所有调用成功时触发,请使用其他 .ajax() 事件处理程序来增加计数器以防出错。

【讨论】:

  • 谢谢,但实际上我在我的问题中将这个解决方案描述为不够优雅,无法满足我的要求。此外,这仍然没有考虑这些图像。
  • @Imp 用于图像(和所有其他资源)添加 $(window).load(function(){addToReadyCount();});
  • 谢谢。根据jQuery 规范,它不太可靠,但确实有帮助。
猜你喜欢
  • 1970-01-01
  • 2013-12-29
  • 2016-08-07
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多