iframe이로드되었는지 또는 콘텐츠가 있는지 확인하는 방법은 무엇입니까?


84

id = "myIframe"인 iframe이 있고 여기에 콘텐츠를로드하는 코드가 있습니다.

$('#myIframe').attr("src", "my_url");

문제는 때로는 로딩에 너무 오래 걸리고 때로는 매우 빠르게 로딩된다는 것입니다. 그래서 "setTimeout"함수를 사용해야합니다.

setTimeout(function(){
   if (//something shows iframe is loaded or has content)
   {
       //my code
   }
   else
   {
       $('#myIframe').attr("src",""); //stop loading content
   }
},5000);

내가 알고 싶은 것은 iFrame이로드되었는지 또는 콘텐츠가 있는지 확인하는 방법입니다. 사용 iframe.contents().find()이 작동하지 않습니다. 사용할 수 없습니다 iframe.load(function(){}).


로드하는 데 5 초 이상 걸리면 iframe이 아무것도로드하지 않도록 하시겠습니까?
skimberk1

당신의 도움을 주셔서 감사합니다 :) . 예,로드하는 데 5 초 이상 걸리는 경우 iframe에서 아무것도로드하지 않기를 바랍니다. ".ready ()"를 사용하면 작동하지 않습니다.
newbie29

여기 내 대답을 참조하십시오 stackoverflow.com/questions/17158932/…
dude

답변:


89

이 시도.

<script>
function checkIframeLoaded() {
    // Get a handle to the iframe element
    var iframe = document.getElementById('i_frame');
    var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

    // Check if loading is complete
    if (  iframeDoc.readyState  == 'complete' ) {
        //iframe.contentWindow.alert("Hello");
        iframe.contentWindow.onload = function(){
            alert("I am loaded");
        };
        // The loading is complete, call the function we want executed once the iframe is loaded
        afterLoading();
        return;
    } 

    // If we are here, it is not loaded. Set things up so we check   the status again in 100 milliseconds
    window.setTimeout(checkIframeLoaded, 100);
}

function afterLoading(){
    alert("I am here");
}
</script>

<body onload="checkIframeLoaded();"> 

21
setTimeout ()에 문자열을 전달할 때의 단점. 함수 참조를 전달하는 것이 더 깔끔합니다.setTimeout(checkIframeLoaded, 100);
Jesse Hallett 2013

1
이로 인해 "URL2 도메인, 프로토콜 및 포트가 일치해야하는 프레임에서 URL url1로 프레임에 액세스하려는 안전하지 않은 JavaScript 시도가 ​​있습니다."
mohamed-ibrahim

이것이 제가 이루고자하는 일에 가장 적합한 솔루션이었습니다. iFrame 내부에서 AngularJS를 사용하고 포함 된 파일의로드를 지연시키는 ng-include를 사용하고 있습니다. onload 이벤트에서 Iframe의 내용을 인쇄하려고했지만 너무 빨리 실행되었습니다. readyState === "complete"모든 것이로드 될 때까지 변경되지 않기 때문에 확인 은 트릭 을 수행했습니다.
Jeffrey A. Gochin

3
나는 이것이 나에게도 효과가 있었던 유일한 해결책이라고 말해야한다. iframe에서로드 이벤트는 대부분의 경우 IE11, Chrome 및 Edge에서 즉시 실행 iframe.contentDocument.location.href되며 about:blank. srcfor iframe가 HTML에서 직접 지정되는 경우에도 마찬가지 입니다.
rmalayter

24
iframe이 다른 도메인에서 가져온 경우에는 작동하지 않습니다.VM29320:1 Uncaught DOMException: Blocked a frame with origin "http://localhost:9002" from accessing a cross-origin frame.
Augustin Riedinger 2016

46

친절하게 사용 :

$('#myIframe').on('load', function(){
    //your code (will be called once iframe is done loading)
});

표준이 변경됨에 따라 내 대답을 업데이트했습니다.


4
이 접근 방식은 이벤트가 즉시 발생하기 때문에 전혀 작동하지 않습니다. iframes는 일반적으로으로 시작 하기 때문 입니다.는 HTML에서 직접 지정되거나 DOM에 노드가 추가 되기 전에도 src="about:blank"마찬가지 입니다. IE11, Chrome 및 Edge에서 긴밀한 루프에서 의 폴링을 통해 이것을 테스트했습니다 . 프레이밍되는 콘텐츠가 메타 태그 또는 자바 스크립트를 통해 리디렉션되는 경우에도 작동하지 않습니다. srciframeiframecontentDocument.location.href
rmalayter

17

나는 동일한 문제가 있었고 이것에 추가하여 교차 도메인 정책에 관계없이 iframe이로드되었는지 확인해야했습니다. 웹 페이지에 특정 스크립트를 삽입하고 상위 페이지의 일부 콘텐츠를 iframe에 표시하는 크롬 확장 프로그램을 개발하고있었습니다. 나는 다음 접근 방식을 시도했고 이것은 나를 위해 완벽하게 작동했습니다.
추신 : 제 경우에는 iframe의 콘텐츠를 제어 할 수 있지만 상위 사이트에서는 제어 할 수 없습니다. (Iframe은 내 서버에서 호스팅됩니다.)

첫째 : 속성이
있는 iframe을 다음과data- 같이 만듭니다 (이 부분은 내 경우 삽입 된 스크립트에 있음).
<iframe id="myiframe" src="http://anyurl.com" data-isloaded="0"></iframe>

이제 iframe 코드에서 다음을 사용합니다.

var sourceURL = document.referrer;
window.parent.postMessage('1',sourceURL);



이제 내 경우에 따라 삽입 된 스크립트로 돌아갑니다.

setTimeout(function(){
  var myIframe = document.getElementById('myiframe');
  var isLoaded = myIframe.prop('data-isloaded');
  if(isLoaded != '1')
  {
    console.log('iframe failed to load');
  } else {
    console.log('iframe loaded');
  }
},3000);


과,

window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
    if(event.origin !== 'https://someWebsite.com') //check origin of message for security reasons
    {
        console.log('URL issues');
        return;
    }
    else {
        var myMsg = event.data;
        if(myMsg == '1'){
            //8-12-18 changed from 'data-isload' to 'data-isloaded
            $("#myiframe").prop('data-isloaded', '1');
        }
    }           
}



질문에 정확하게 대답하지 않을 수도 있지만 실제로이 방법으로 해결 한이 질문의 가능한 경우입니다.


코드에 document.getElement-> s <-ById와 같은 오류가 있지만 전체 아이디어가 유용합니다. 효과가있다. 감사합니다)
JohnK

@JohnK 지적 해 주셔서 감사합니다. 이것이 당신에게 유용하다는 것을 알게되어 기쁩니다.
Tushar Shukla

12

가장 쉬운 옵션 :

<script type="text/javascript">
  function frameload(){
   alert("iframe loaded")
  }
</script>

<iframe onload="frameload()" src=...>

10
URL이 깨져도 경고를 제공하므로 솔리드 솔루션이 아닙니다.
bboy

7

iframe의 load이벤트를 사용하여 iframe이로드 될 때 응답 할 수 있습니다 .

document.querySelector('iframe').onload = function(){
    console.log('iframe loaded');
};

이것은 올바른 콘텐츠가로드되었는지 여부를 알려주지 않습니다.이를 확인하려면 contentDocument.

document.querySelector('iframe').onload = function(){
    var iframeBody = this.contentDocument.body;
    console.log('iframe loaded, body is: ', body);
};

contentDocumentiframe이 src코드가 실행중인 도메인과 다른 도메인을 가리키는 경우 확인이 작동하지 않습니다 .


2
코드가 수행하는 작업과 문제를 해결하는 이유에 대한 설명을 추가하려면 게시물을 편집하는 것이 좋습니다. 대부분 코드 만 포함하는 답변 (작동 중이더라도)은 일반적으로 OP가 문제를 이해하는 데 도움이되지 않습니다.
SuperBiasedMan

5

로드되었는지 여부를 감지 할 수 있는지 확실하지 않지만로드가 완료되면 이벤트를 실행할 수 있습니다.

$(function(){
    $('#myIframe').ready(function(){
        //your code (will be called once iframe is done loading)
    });
});

편집 : Jesse Hallett이 지적했듯이 iframe이미로드 된 경우에도로드 되면 항상 실행됩니다 . 따라서 기본적으로 iframe가 이미로드 된 경우 콜백이 즉시 실행됩니다.


2
이 방법의 좋은 점은 iframe이 완전히로드 된 후 바인딩하더라도 jQuery 'ready'이벤트가 발생한다는 것입니다. 따라서 iframe에 이미 콘텐츠가 있는지 확인하거나 콘텐츠가 도착하면 알리는 좋은 방법입니다.
Jesse Hallett 2013

1
이것은 iframe에 대해 한 번만 실행되는 것으로 보입니다. 그러나 iframe에 iframe의 콘텐츠가 다시로드 될 수있는 링크가있는 경우이 이벤트는 다시 실행되지 않습니다. 이 경우 귀하의 경우는 @pratikabu으로 대답을 사용 -$('#myIframe').load(function(){ })
ragamufin

@ skimberk1 안녕하세요,이 답변 에 따르면 jquery는 DOM 이로 드되었는지 기억할 변수를 보유하고 iframe의 DOM이 아닌 현재 프레임의 현재 DOM을 확인하기 때문에 솔루션 이 작동하지 않습니다.
Marco Medrano 2014 년

그래, 당신은 ..., 이벤트를 발생 매우 유익한, 준비가되면 비디오, 음악을 재생을 표시 할 수 있습니다
Giridhar Karnik

이 티켓에 따르면 : iframe에서 사용 하는 dev.jquery.com/ticket/5511ready 은 jQuery가 실행되는 프레임이 아닌 다른 문서에서는 지원되지 않으므로 항상 즉시 함수를 실행합니다.
친구

5

제 경우에는 교차 출처 프레임이었고 가끔로드되지 않았습니다. 나를 위해 일한 해결책은 다음과 같습니다. 성공적으로로드되면이 코드를 시도하면 :

var iframe = document.getElementsByTagName('iframe')[0];
console.log(iframe.contentDocument);

contentDocument교차 출처 오류 에 액세스 하고 던지는 것을 허용하지 않지만 프레임이 성공적으로로드되지 않으면 객체 contentDocument를 반환 #document합니다.


2

iFrame이로드 될 때 처음에는 #document가 포함되므로로드 상태를 확인하는 것이 가장 효과적 일 수 있습니다.

if ($('iframe').contents().find('body').children().length > 0) {
    // is loaded
} else {
    // is not loaded
}

6
다른 도메인에있는 경우 실패합니다
Funkodebat

iframe이로드 중일 수 있으므로 (완전히로드되지 않음) 이는 잘못된 것입니다.
Mike Shiyan

1

다음과 같이 작동하는 트릭이 있습니다. [브라우저 간 테스트하지 않았습니다!]

iframe의 onload 이벤트 핸들러를 다음과 같이 정의하십시오.

$('#myIframe').on('load', function() {
    setTimeout(function() {
        try {
            console.log($('#myIframe')[0].contentWindow.document);
        } catch (e) {
            console.log(e);
            if (e.message.indexOf('Blocked a frame with origin') > -1 || e.message.indexOf('from accessing a cross-origin frame.') > -1) {
                alert('Same origin Iframe error found!!!');
                //Do fallback handling if you want here
            }
        }
    }, 1000);

});

면책 조항 : SAME ORIGIN IFRAME 문서에서만 작동합니다.


0

정말 좋은 방법은 jQuery AJAX를 사용하는 것입니다. 상위 프레임은 다음과 같습니다.

<iframe src="iframe_load.php" style="width: 100%; height: 100%;"></iframe>

iframe_load.php 파일은 AJAX GET에서 대상 URL을로드하려고 시도하는 jQuery 라이브러리와 JavaScript를로드합니다.

var the_url_to_load = "http://www.your-website.com" ;
$.ajax({
            type: "GET",
            url: the_url_to_load,
            data: "",
            success: function(data){
                // if can load inside iframe, load the URL
                location.href = the_url_to_load ;
            },
            statusCode: {
                500: function() {
                    alert( 'site has errors' ) ;
                }
            },
            error:function (xhr, ajaxOptions, thrownError){
                // if x-frame-options, site is down or web server is down
                alert( 'URL did not load due to x-frame-options' ) ;
            } });

중요 대상에는 "Access-Control-Allow-Origin"헤더가 있어야합니다. PHP의 예 :

HEADER( "Access-Control-Allow-Origin: *" ) ;

0

iframe을 조작 할 준비가 된시기를 알아야하는 경우 간격을 사용하십시오. 이 경우 I "핑 (ping)"내용 모든 250 MS와이 있다면 어떤 대상은 iframe 내부의 내용은 "핑 (ping)"을 중단하고 뭔가를이.

var checkIframeLoadedInterval = setInterval( checkIframeLoaded, 250 );

function checkIframeLoaded() {
    var iframe_content = $('iframe').contents();

    if (iframe_content.length > 0) {
        clearInterval(checkIframeLoadedInterval);

        //Apply styles to the button
        setTimeout(function () {
            //Do something inside the iframe 
            iframe_content.find("body .whatever").css("background-color", "red");
        }, 100); //100 ms of grace time
    }
}

0

동일한 도메인 에서 페이지와 iframe을 호스팅하는 경우 iframe의 Window.DOMContentLoaded이벤트를 수신 할 수 있습니다 . 원본 페이지가 DOMContentLoaded먼저 실행될 때까지 기다린 다음 DOMContentLoadediframe의 이벤트 리스너 를 연결해야합니다.Window .

다음과 같은 iframe이있는 경우

<iframe id="iframe-id" name="iframe-name" src="..."></iframe>

다음 스 니펫을 사용하면 iframe의 DOMContentLoaded이벤트 에 연결할 수 있습니다 .

document.addEventListener('DOMContentLoaded', function () {
    var iframeWindow = frames['iframe-name'];
    // var iframeWindow = document.querySelector('#iframe-id').contentWindow
    // var iframeWindow = document.getElementById('iframe-id').contentWindow

    iframeWindow.addEventListener('DOMContentLoaded', function () {
        console.log('iframe DOM is loaded!');
    });
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.