6

So I create an iframe and it's supposed to continue reloading after a function runs. The function reads info that is in the iframe. Currently I have something like this (Which works);

function loaded(){
    alert(iframe.contentDocument.getElementsByClassName("blah")[0].innerHTML);
    iframe.src = filePath; //reloads the iframe
}

iframe.onload = loaded;

Because i'de like it to execute faster, would something like this work; Where the function runs as soon as the iframe has loaded the DOM;

function loaded(){
    alert(iframe.contentDocument.getElementsByClassName("blah")[0].innerHTML);
    iframe.src = filePath; //reloads the iframe
}

iframe.addEventListener("DOMContentLoaded", loaded, false);
Alex
  • 1,035
  • 3
  • 16
  • 31
  • 1
    [There is no reliable cross-browser way to do this.](https://bugs.webkit.org/show_bug.cgi?id=33604) – lonesomeday Jun 06 '13 at 22:35
  • possible duplicate of [How to properly receive the DOMContentLoaded event from an XUL iframe?](http://stackoverflow.com/questions/11174359/how-to-properly-receive-the-domcontentloaded-event-from-an-xul-iframe) – user692942 May 28 '14 at 10:36

2 Answers2

3

The best you can do is to use the Messaging API.

From your <iframe> document, you'd send a message to its parent letting it know the DOM has loaded.

const iframe = document.getElementById( 'iframe' );
// set up the event handler on main page
window.addEventListener( 'message', (evt) => {
  if( evt.source === iframe.contentWindow) {
    console.log( evt.data );
  }
} );
iframe.onload = (evt) => console.log( 'onload' );

// For the snippet, we'll load the iframe document from a Blob
const iframe_document = new Blob( [`
<script>
  document.addEventListener( 'DOMContentLoaded', (evt) => {
    // tell the parent window we are ready
    parent.postMessage( 'DOM loaded', '*' );
  });
<\/script>
<h1>Hello world</h1>
<img src='https://i.picsum.photos/id/13/500/300.jpg?${Math.random()}' style="border:1px solid">
`], { type: "text/html" } );
iframe.src = URL.createObjectURL( iframe_document );
<iframe id="iframe" width="520" height="500"></iframe>
Kaiido
  • 123,334
  • 13
  • 219
  • 285
0
iframe.onreadystatechange = () => {
    if (iframe.readyState === "interactive") {
        // your code here
    }
};

I understand, that it's a very old question, but using google I found this one, when I was looking for a solving of this trouble

kkbur
  • 17
  • 5
  • `iframe` is an HTML – Kaiido Mar 19 '20 at 00:53
  • @Kaiido Perhaps they meant `iframe.contentDocument.onreadystatechange`? – Nanoo Nov 14 '20 at 14:45
  • @Nanoo but it's not what they wrote, and if they can access the `iframe.contentDocument` then they could directly attach the DOMContentLoaded event listener from there, but they can't because before the iframe loads you can't access the contentDocument -> back to square one. – Kaiido Nov 14 '20 at 15:23
  • @Kaiido `iframe.contentDocument` does not fire the DOMContentLoaded event. – Nanoo Nov 14 '20 at 20:30
  • @Nanoo ... Where did I say it does? I sid it doesn't fire onreadytatechange event. You said they probably meant `iframe.contentDocument` and I said that if they had access to `iframe.contentDocument` they could attach the DOMContentLoaded event to it directly, but they don't have access to this contentDocument anyway, and that's the whole point of the question. – Kaiido Nov 15 '20 at 00:42