Wayne
Wayne

Reputation: 363

Infinite loading with script tag inside iframe

Here is code, stuck with that simple issue which I never have had in past 7 years:

<html>
<body>
    <iframe></iframe>
    <script>
        window.frames[0].document.write('<scr' + 'ipt type="text/javascript" src="//code.jquery.com/jquery-3.0.0.min.js"><\/scr' + 'ipt>');
    </script>
</body>
</html>

The problem is that browser's spin wheel continue to circle.

Network console shows all loaded.

If I remove iframe from DOM, or add/change @src attribute - loading stops.

Upvotes: 3

Views: 3470

Answers (6)

ITW
ITW

Reputation: 482

May use the onload

function populateIFrame() {
        const str = `<body></body>`;
        const idoc = document.getElementById("demo01")
        idoc.contentDocument.write(str)
        idoc.close();
}

window.onload=populateIFrame

Upvotes: 0

JD Byrnes
JD Byrnes

Reputation: 831

I believe the first answer is the better way, but I'll provide a second answer that is almost identical to your code, but shows how calling document.close() would have also solved your issue.

The issue is that you've started writing to the document's <head> element in the iFrame, but not finished (that's why the page keeps loading). Calling document.close() signals that you've finished writing to the document.

<html>
  <body>
    <iframe></iframe>
    <script>
      var doc = window.frames[0].document
      doc.write('<scr' + 'ipt type="text/javascript" src="//code.jquery.com/jquery-3.0.0.min.js"><\/scr' + 'ipt>');
      doc.close();
    </script>
  </body>
</html>

Upvotes: 8

JD Byrnes
JD Byrnes

Reputation: 831

I was able to insert the script without the loading issue you describe by defining and appending the element in Javascript, without any loading issues.

<html>
  <body>
    <iframe id="myFrame"></iframe>
    <script>
      var jq = document.createElement('script')
      jq.type = 'text/javascript'
      jq.src = '//code.jquery.com/jquery-3.0.0.min.js'
      document.getElementById('myFrame').contentDocument.getElementsByTagName('body')[0].appendChild(jq);
    </script>
  </body>
</html>

Of course, changing body to head will change where the script loads in the iFrame.

Upvotes: 0

Wayne
Wayne

Reputation: 363

Actually, I've just found solution that works if you have control on inner script (doesn't help with loading 3rd party like jQ though).

You should close "current stream" with document.close().

Upvotes: 2

vsync
vsync

Reputation: 130055

Try just:

window.frames[0].document.write('<script type="text/javascript" src="//code.jquery.com/jquery-3.0.0.min.js"><\/script>');

I checked on JSbin and it works ok. Example page


Update:

I think it cannot work because that iframe doesn't even have any document in it. it's just an empty tag until it has a working src and is populated. See demo

Anyway, this can only work if the content of the iframe is on the same domain (google "cross-origin iframes"). There is a "race" going on here. you want to load jQuery so the page your are loading would use it, but you cannot load any script from the outside of the iframe to the inside until the page has loaded inside the iframe...

Upvotes: 0

memimomu
memimomu

Reputation: 161

Looks like firefox might have some weirdness around iframes

<html>
  <body>
    <iframe></iframe>
    <script>setTimeout(function(){window.frames[0].document.write("hi");}, 5000);</script>
  </body>
</html>

This results in a spinner that starts 5 seconds after page load and doesn't go away (at least on my computer - firefox 47.0)

Upvotes: 0

Related Questions