[英]'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
更安全,因为变量parent
和top
可能会被覆盖(通常不是故意的)。
你必须考虑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。 我想出了以下解决方案:
功能:
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.