[英]'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.