【问题标题】:Removing loader animation after iframes have loaded加载 iframe 后删除加载器动画
【发布时间】:2016-02-22 20:57:33
【问题描述】:

我正在维护一个将所有内容都包含在 iframe 中的 Web 应用程序。对其结构的快速分解:(每个'-'代表一个新层)

Main page
-iframe container
--iframe q1
--iframe q2
--iframe q3
--iframe q4
--iframe q5

基本上,一个主框架内有 4 个 iFrame。我有一个加载器动画,我需要在所有 iframe 完成加载后从屏幕上删除它。每个 iframe 都有数据,这些数据通过页面上的选择进行更新。我需要的是每次更新后加载动画覆盖整个屏幕。处理此问题的最佳方法是什么?我知道你可以使用

$('#iframe').on('load',function() {
      //code here...
}

确定 iframe 何时完成加载。有没有一种简单的方法可以一次收听所有这些,然后在它们完成后关闭加载动画?感谢您的帮助。

以下是每个 iframe 的创建方式:

var p1HTML = '<div id='p1ContainerBody' class='panelContainerBody'><iframe id='P1ChartFrame' src='' frameborder='0' scrolling='no' style='height: 100%; width: 100%'></iframe></div>'

然后:

if (ConfigData["GlobalOptions"].Quadrants[x].QuadrantId == "1") { $("#q1Container").html(p1HTML); }

【问题讨论】:

  • 您是以编程方式创建每个 iframe 还是在 HTML 中实例化它们?
  • 您是指每个 iframe 内部的内容,还是 iframe 本身?
  • @zero298 我更新了我的帖子以显示它是如何完成的

标签: javascript jquery iframe loading-animation


【解决方案1】:

为每个iframe 创建一个Promise 并添加一个load 侦听器,正如您在第二个代码块中讨论的那样。在 iframe 加载后,在 load 事件监听器中解析 Promise。创建一个Promise.all() 处理程序以在所有iframes 加载后删除动画。

Promise.all(Array.prototype.map.call(document.querySelectorAll("iframe"), function (iframe) {
    return new Promise(function (resolve, reject) {
        iframe.addEventListener("load", function () {
            resolve();
        });
    });
})).then(function () {
    // Do loading removal
});

如果您希望留在 jQuery 框架内,jQuery 有自己的 Promise API

您需要做的主要事情是保留iframes 的句柄,以便您可以在更改它们指向的url 之前将显式加载处理程序附加到它们。如果不这样做,您可能会在位置被缓存或其他情况下错过加载事件。

考虑这个替代代码:

var urlArr, iframeProms;

// Array of urls that we need to make iframes for
urlArr = [
    "http://www.google.com",
    "http://www.yahoo.com"
];

// Map the urls to an array of objects containing iframe elements and associated promises
iframeProms = $.map(urlArr, function (url) {
    var d, iframe;

    // Make a deferred that we will resolve on iframe load
    d = $.Deferred();

    // Make an iframe
    iframe = $("iframe");

    // Add a load listener BEFORE YOU ADD THE URL
    iframe.on("load", function () {
        // Resolve the deferred
        d.resolve();
    });

    // Now provide the url so we don't miss timing for load event
    iframe.src = url;

    // Return a handle to the iframe and the deferred's promise
    return {
        i: iframe,
        p: d.promise
    };
});

// Map down to the promises and what for them to resolve
$.when($.map(iframeProms, function (i) {
    return i.p;
})).then(function () {
    // Do loading removal
});

【讨论】:

  • 每个 Promise 会进入其各自的 iframe 内,还是在最内层 iframe 之外创建,但在主要 iframe 内创建?
  • @NickRoberto 哪个层控制显示加载屏幕。我想说第二级iframe 容器是正确的选择。但是,如果您想进一步嵌套,则需要与 window.postMessage() 一起跳舞,并更改您的 Promise 解析器以在收到相应消息时解析。
  • 啊,我在您发布的链接上看到 Promise 不支持 IE。尽管听起来很奇怪,但大多数使用该网站的客户端都在 IE 中运行它,所以它必须在那里工作。
猜你喜欢
  • 2018-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-22
  • 2020-01-02
相关资源
最近更新 更多