Iframe 콘텐츠가로드 된시기 감지 (크로스 브라우저)


91

iframe과 해당 콘텐츠가로드되었지만 운이 좋지 않은시기를 감지하려고합니다. 내 응용 프로그램은 상위 창의 텍스트 필드에 일부 입력을 받고 iframe을 업데이트하여 '실시간 미리보기'를 제공합니다.

iframe로드 이벤트가 발생하는시기를 감지하기 위해 다음 코드 (YUI)로 시작했습니다.

$E.on('preview-pane', 'load', function(){
    previewBody = $('preview-pane').contentWindow.document.getElementsByTagName('body')[0];
}

'preview-pane'은 내 iframe의 ID이며 YUI를 사용하여 이벤트 핸들러를 연결하고 있습니다. 그러나 내 콜백에서 본문에 액세스하려는 시도 (iframe로드시)가 실패합니다. 이벤트 핸들러가 준비되기 전에 iframe이로드되기 때문이라고 생각합니다. 이 코드는 iframe을 생성하는 PHP 스크립트를 절전 모드로 만들어 iframe로드를 지연하는 경우 작동합니다.

기본적으로 iframe이로드되고 문서가 준비된시기를 감지하기 위해 브라우저에서 올바른 접근 방식이 무엇인지 묻습니다.


1
YUI로 시작하는 것은 나쁜 생각입니다 (다른 JS 라이브러리와 마찬가지로). 왜? 도서관이 어떤 마법을하는지 알 수 없기 때문입니다. "로드"를 완전히 지원할 수없는 경우 명확하고 읽기 쉬운 자바 스크립트로 직접 수행하는 것이 좋습니다.
Christian

2
@Christian 라이브러리의 소스 코드를 자주 읽을 수 있습니다. 일반적으로 구현 사용 여부에 관계없이 직접 수행하는 방법에 대한 훌륭한 팁을 제공합니다.
AJP 2013 년

@AJP 당신은 내 요점을 오해했습니다. 확실하지 않은 작업을 수행하는 경우 코드를 적게 사용하여 오류의 여지를 줄이는 것이 좋습니다.
기독교

2
당신이 그것을 어떻게 보는지에 달려 있습니다. 당시 YUI의 이벤트 처리가 작동한다는 것을 알고 있었으므로 코드의 해당 부분에 대해 걱정할 필요가 없었습니다. 나는 또한 내 자신의 addEvent 핸들러를 작성하는 방법을 알고 있었지만이 문제와 관련하여 YUI보다 더 잘 작동하지 않았습니다.
David Snabel-Caunt 2013 년

1
@Nico 질문은 YUI를 나타내고 $는 YUI의 Dom 래퍼에 대한 별칭입니다.
David Snabel-Caunt 2014

답변:


73

iframe이로드되고 문서가 준비된시기를 감지하려면?

iframe이 프레임 내부의 스크립트에서 자신을 알려주는 것이 이상적입니다. 예를 들어 부모 함수를 직접 호출하여 준비되었음을 알릴 수 있습니다. 예상치 못한 순서로 일이 발생할 수 있으므로 프레임 간 코드 실행에는 항상주의가 필요합니다. 또 다른 대안은 'var isready = true;'를 설정하는 것입니다. 자체 범위에서 부모 스크립트가 'contentWindow.isready'에 대해 스니핑하도록합니다 (그렇지 않으면 onload 핸들러를 추가합니다).

어떤 이유로 iframe 문서가 협력하는 것이 실용적이지 않다면 기존의로드-레이스 문제, 즉 요소가 서로 바로 옆에 있더라도 다음과 같은 문제가 있습니다.

<img id="x" ... />
<script type="text/javascript">
    document.getElementById('x').onload= function() {
        ...
    };
</script>

스크립트가 실행될 때 항목이 이미로드되지 않았다는 보장은 없습니다.

로드 레이스에서 벗어나는 방법은 다음과 같습니다.

  1. IE에서는 'readyState'속성을 사용하여 이미로드되었는지 확인할 수 있습니다.

  2. JavaScript가 활성화 된 상태에서만 항목을 사용할 수있는 경우 소스를 설정하고 페이지에 추가하기 전에 'onload'이벤트 기능을 설정하여 동적으로 생성 할 수 있습니다. 이 경우 콜백이 설정되기 전에로드 할 수 없습니다.

  3. 마크 업에 포함하는 구식 방식 :

    <img onload="callback(this)" ... />

HTML의 인라인 'onsomething'핸들러는 거의 항상 잘못된 것이며 피해야합니다. 그러나이 경우에는 때때로 가장 나쁜 옵션입니다.


감사. 내 솔루션은 readyState (존재하는 경우)를 확인한 다음 body 요소 innerHTML 길이를 확인하여로드되었는지 확인합니다. 그렇지 않은 경우로드 이벤트 핸들러를 연결합니다.
괜찮은

8
-1-인라인 이벤트는 "나쁜"것이 아니라 현재 유행 일뿐입니다. 실제로 인라인 이벤트는 마법에 해당하는 것과 달리 디버그하고 이해하기가 더 쉽습니다 (반면에 연결, 스택 및 원활하게 사용하기가 더 쉽습니다).
Christian

1
@Christian, 인라인 이벤트는 매우 긴 목록의 모든 요소에 이벤트를 첨부해야 할 때 가장 좋은 옵션입니다. 이미 서버 측에서 목록을 작성하기 위해 반복하고 있으므로 인라인 이벤트도 첨부하는 것이 훨씬 더 효율적입니다.
haknick

16
@haknick 목록에서 단일 이벤트 리스너를 사용하고 이벤트 델리게이트를 사용하고 싶지 않습니까? 이것은 더 효율적입니다.
David Snabel-Caunt 2011

4
iframe이 교차 도메인 인 경우 작동하지 않습니다. iframe 내부의 스크립트는 상위 창에 액세스 할 수 없습니다.
Sudheer Someshwara

48

블로그 게시물을 참조하십시오 . jQuery를 사용하지만 사용하지 않더라도 도움이 될 것입니다.

기본적으로 이것을 당신의 document.ready()

$('iframe').load(function() {
    RunAfterIFrameLoaded();
});

흥미롭지 만 제가 가진 문제는로드 이벤트와 타이밍에 있습니다. 해당 기사에서 조언 한대로로드 이벤트를 듣고 있습니다.
David Snabel-Caunt 2009

나는 이것을 시도했다 console.log. iframe이로드 된 후 기록됩니다.
shorif2000 2015 년

12

React를 사용하는 경우 동일 출처 iframe로드 이벤트를 감지하는 것은 onLoadiframe 요소에 이벤트 리스너를 설정하는 것만 큼 간단합니다 .

<iframe src={'path-to-iframe-source'} onLoad={this.loadListener} frameBorder={0} />


onLoad이벤트가 동일 출처 iframe에 대해서만 트리거 될 수 있습니까 ?
L_K

2

Ember를 사용하는 모든 사람은 예상대로 작동합니다.

<iframe onLoad={{action 'actionName'}}  frameborder='0' src={{iframeSrc}} />
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.