Chrome에서 iframe을 로드할 때 'load' 이벤트가 발생하지 않음
파일이 동적으로 생성되는 서버 측에서 클라이언트에 '마스크'를 표시하려고 합니다.(ajax가 아니기 때문에) 이 문제를 회피하려면 iframe을 사용하여 온로드 이벤트 또는 완료 이벤트로부터 파일을 수신하여 실제로 서버에서 클라이언트에 언제 발송했는지 확인하는 것이 좋습니다.
각도 코드는 다음과 같습니다.
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에서는 잘 작동하지 않습니다.또, 온로드 기능을 사용해 보았습니다.
e.onload = function() { //unmask here }
하지만 나는 거기서도 운이 없었다.
아이디어?
유감스럽게도 iframe은 사용할 수 없습니다.onload
첨부 파일인 경우 Chrome에서 이벤트를 발생시킵니다.이 답변을 통해 대처 방법에 대한 아이디어를 얻을 수 있습니다.
정말 싫지만, 가끔 확인하는 것 외에는 아직 로딩 중인지 아닌지를 확인할 방법이 없었습니다.
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
덮어쓸 수 있습니다(통상은 의도하지 않습니다).
다음 두 가지 사항을 고려해야 합니다.
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
});
};
모든 종류의 브라우저에서 이 작업을 수행해 왔습니다.
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');
})
JQuery
기능:
$.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');
})
Chrome이 항상 메인 페이지에서 로드 이벤트를 실행하는 것은 아니기 때문에 기본적으로 동일하게 취급되기 때문에 iframe에도 영향을 줄 수 있습니다.
Dev Tools 또는 Performance api를 사용하여 로드 이벤트가 실행되고 있는지 확인합니다.
방금 http://ee.co.uk/을 확인했는데 콘솔을 열고 창을 열면 됩니다.performance.timing domComplete, loadEventStart 및 loadEventEnd 엔트리는 적어도 현시점에서는0 입니다).
Chrome에 문제가 있는 것 같습니다.최신 버전 31.0.1650.63을 사용하여 2대의 PC에서 확인했습니다.
업데이트: ee를 다시 체크하고 이벤트를 로드하지만 이후 새로고침에서는 로드하지 않습니다.따라서 이것은 간헐적이며 해당 사이트의 로드 오류와 관련이 있을 수 있습니다.하지만 부하 이벤트는 무엇이든 발사해야 합니다.
이 문제는 사이트 모니터링이 가끔 실패하는 것을 알게 된 이후 마지막 날 현재 5~6개 사이트에서 발생했습니다.방금 원인을 알아냈을 뿐이죠잠을 좀 자야겠어요. 그리고 좀 더 깨어있을 때 자세히 조사할 거예요.
언급URL : https://stackoverflow.com/questions/20572734/load-event-not-firing-when-iframe-is-loaded-in-chrome
'it-source' 카테고리의 다른 글
AngularJS 자원 약속 (0) | 2023.02.16 |
---|---|
어레이 파괴 시 유형 (0) | 2023.02.16 |
LIKE 연산자에 여러 조건을 도입하려면 어떻게 해야 하나요? (0) | 2023.02.16 |
파라미터를 jQuery의 .load()에 전달하는 가장 좋은 방법 (0) | 2023.02.16 |
Spring @ReponseBody @RequestBody(추상 클래스 포함) (0) | 2023.02.16 |