繁体   English   中英

在 Chrome 中加载 iframe 时不会触发“加载”事件

[英]'load' event not firing when iframe is loaded in Chrome

我试图在我的客户端上显示一个“掩码”,而文件是动态生成的服务器端。 似乎推荐的解决方法(因为它不是 ajax)是使用 iframe 并从 onload 或 done 事件中侦听以确定文件何时从服务器实际发送到客户端。

这是我的角度代码:

    var url = // url to my api
    var e = angular.element("<iframe style='display:none' src=" + url + "></iframe>");
    e.load(function() {
        $scope.$apply(function() {
            $scope.exporting = false;  // this will remove the mask/spinner
        });
    });
    angular.element('body').append(e);

这在 Firefox 中效果很好,但在 Chrome 中没有运气。 我也尝试过使用 onload 函数:

e.onload = function()  { //unmask here }

但我在那里也没有任何运气。

想法?

不幸的是,如果内容是附件,则无法在 Chrome 中使用 iframe 的onload事件。 这个答案可能会让您了解如何解决它。

我讨厌这一点,但除了定期检查之外,我找不到任何其他方法,只能检查它是否仍在加载。

var timer = setInterval(function () {
    iframe = document.getElementById('iframedownload');
    var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
    // Check if loading is complete
    if (iframeDoc.readyState == 'complete' || iframeDoc.readyState == 'interactive') {
        loadingOff();
        clearInterval(timer);
        return;
    }
}, 4000);

你可以用另一种方式做到这一点:

在主文档中:

function iframeLoaded() {
     $scope.$apply(function() {
            $scope.exporting = false;  // this will remove the mask/spinner
        });
}

var url = // url to my api
var e = angular.element("<iframe style='display:none' src=" + url + "></iframe>");
angular.element('body').append(e);

在 iframe 文档中(即,在 url 引用的页面的 html 中)

    window.onload = function() {
        parent.iframeLoaded();
    }

如果主页和 iframe 内的页面在同一个域中,这将起作用。

实际上,您可以通过以下方式访问父级:

window.parent
parent
//and, if the parent is the top-level document, and not inside another frame
top          
window.top

使用window.parent更安全,因为变量parenttop可能会被覆盖(通常不是故意的)。

你必须考虑2点:

1-首先,如果您的 url 具有不同的域名,则无法执行此操作,除非您有权访问其他域以添加Access-Control-Allow-Origin: *标头,要解决此问题,请转到此链接

2-但如果它具有相同的域或者您已将Access-Control-Allow-Origin: *到域的标头中,您可以像这样执行您想要的操作:

var url = // url to my api
var e = angular.element("<iframe style='display:none' src=" + url + "></iframe>");
angular.element(document.body).append(e);
e[0].contentWindow.onload = function() {
    $scope.$apply(function() {
        $scope.exporting = false;  // this will remove the mask/spinner
    });
};

我已经在各种浏览器中做到了这一点。

我刚刚注意到 Chrome 并不总是为主页触发加载事件,因此这也可能对 iframe 产生影响,因为它们基本上以相同的方式处理。

使用 Dev Tools 或 Performance api 检查是否正在触发 load 事件。

我刚刚检查了http://ee.co.uk/ ,如果您打开控制台并输入 window.performance.timing,您会发现 domComplete、loadEventStart 和 loadEventEnd 的条目为 0 - 至少在当前时间:)

看起来这里的 Chrome 有问题 - 我已经使用最新版本 31.0.1650.63 在 2 台 PC 上检查了它。

更新:再次检查 ee 并触发 load 事件,但不会在随后的重新加载时触发,因此这是间歇性的,可能与他们网站上的加载错误有关。 但是加载事件应该触发任何事情。

自从我注意到我自己的站点监控偶尔会失败以来,这个问题在最后一天发生在我的 5 或 6 个站点上。 只是查明了这个原因。 我需要睡个美容觉,等我更清醒的时候再调查。

我遇到了 iframe 加载时间过长的问题。 在未处理请求时注册为已加载的 iframe。 我想出了以下解决方案:

JS

功能:

function iframeReloaded(iframe, callback) {
    let state = iframe.contentDocument.readyState;
    let checkLoad = setInterval(() => {
        if (state !== iframe.contentDocument.readyState) {
            if (iframe.contentDocument.readyState === 'complete') {
                clearInterval(checkLoad);
                callback();
            }
            state = iframe.contentDocument.readyState;
        }
    }, 200)
}

用法:

iframeReloaded(iframe[0], function () {
    console.log('Reloaded');
})

查询

功能:

$.fn.iframeReloaded = function (callback) {
    if (!this.is('iframe')) {
        throw new Error('The element is not an iFrame, please provide the correct element');
    }

    let iframe = this[0];
    let state = iframe.contentDocument.readyState;
    let checkLoad = setInterval(() => {
        if (state !== iframe.contentDocument.readyState) {
            if (iframe.contentDocument.readyState === 'complete') {
                clearInterval(checkLoad);
                callback();
            }
            state = iframe.contentDocument.readyState;
        }
    }, 200)
}

用法:

iframe.iframeReloaded(function () {
    console.log('Reloaded');
})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM