0

我有一个网页,其大部分内容是在前端用 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 请求是异步的。也许将处理程序附加到每个请求,然后检查所有请求是否都已完成是做我想做的一种方法,但我正在寻找更优雅的东西。

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

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

4

3 回答 3

1

您正在寻找.ajaxStop().

像这样使用:

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

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

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

于 2012-05-03T20:26:00.897 回答
1

如此处所述,您可以单个图像最终加载时为它们注册加载事件。但是,正如那里所描述的那样,这可能在浏览器之间不可靠,或者如果图像已经在浏览器的缓存中。所以我认为至少有一部分不是 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。这样你就不会被困在等待一个永远不会发生的事件。

于 2012-05-03T20:57:00.343 回答
0

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

在同一函数中检查您的 readyCount 并触发事件处理程序

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

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

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

于 2012-05-03T20:20:40.187 回答