我正在尝试在客户端上显示“掩码”,而文件是在服务器端动态生成的。似乎推荐解决此问题(因为它不是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 }
但我也没有运气。
想法?
答案 0 :(得分:20)
很遗憾,如果内容是附件,则无法在Chrome中使用iframe的onload
事件。这个answer可以让您了解如何解决它。
答案 1 :(得分:10)
我讨厌这个,但除了每隔一段时间检查一次之外,除了检查它是否仍在加载之外,我找不到任何其他方式。
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);
答案 2 :(得分:4)
你可以用另一种方式做到:
在主要文件中:
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
更安全,因为变量parent
和top
可能会被覆盖(通常不是意图)。
答案 3 :(得分:0)
你必须考虑2分:
1-首先,如果您的网址具有不同的域名,则除非您有权访问其他域以添加Access-Control-Allow-Origin: *
标头,否则无法执行此操作,要解决此问题,请转到此{ {3}}
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
});
};
我已在各种浏览器中完成此操作。
答案 4 :(得分:0)
我刚刚注意到Chrome并不总是触发主页面的加载事件,所以这可能会对iframe产生影响,因为它们的处理基本相同。
使用Dev Tools或Performance api检查是否正在触发加载事件。
我刚检查了http://ee.co.uk/,如果你打开控制台并输入window.performance.timing,你会发现domComplete,loadEventStart和loadEventEnd的条目都是0 - 至少在当前时间:)
看起来这里的Chrome存在问题 - 我在2台电脑上使用最新版本31.0.1650.63进行了检查。
更新:再次检查ee并加载事件但未在后续重新加载时触发,因此这是间歇性的,可能与其网站上的加载错误有关。但是加载事件应该触发任何东西。
由于我发现自己的网站监控偶尔会失败,所以在最后一天我在5或6个网站上发生了这个问题。只是找到了原因。我需要一些美容睡眠然后当我更清醒的时候我会进一步调查。
答案 5 :(得分:0)
我遇到了 iframe 加载时间过长的问题。在未处理请求时注册为已加载的 iframe。我想出了以下解决方案:
功能:
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');
})