簡體   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