Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reloading iframe from separate iframe

I have checked all the reload iframe from another iframe posts on stackoverflow...and I have tried all their solutions but it doesn't seem to help me! So my problem is that I have two iframes on the same page. The iframe's sources are php files that interact with each other, however I need the iframes to reload that way the changes are shown. I have tried many different ways (which I will list below). These iframes are from the same domain. Maybe it is something else that is messing this up? Thanks in advance.

Different statements called from inside one iframe:

parent.document.getElementById(id).src = parent.document.getElementById(id).src;
parent.getElementById(id).location.reload();

Trying to call a parent function that works in the parent window:

Inside iframe -

parent.refresh(id);

Parent window working function -

function refresh(id) {
document.getElementById(id).src = document.getElementById(id).src;
}
like image 781
Spencer May Avatar asked Jan 13 '23 01:01

Spencer May


1 Answers

If you assign name to iframe most browsers will let you access the iframe's window object via the name value. This is different from referring to an iframe by its id property which will give you a reference to the iframe element itself (from its owner document), and not the iframe's content window.

Simple Example: (from the parent document)

<iframe name='iframe1Name' id='iframe1Id'></iframe>
<script>
    // option 1: get a reference to the iframe element:
    var iframeElem = document.getElementById('iframe1Id');

    // update the element's src:
    iframeElem.src = "page.html";

    // option 2: get a reference to the iframe's window object:
    var iframeWindow = window.iframe1Name;    

    // update the iframe's location:
    iframeWindow.location.href = "page.html";
</script>

Let's review your code:

parent.document.getElementById(id).src = parent.document.getElementById(id).src;

This works if executed from within the iframe, provided you use the correct id. You may want to use a debugger to verify that parent.document.getElementById(id) returns a reference to the correct element, and check your console to see if any exceptions are being thrown (try hitting F12). Since you didn't post your full code (including markup) there's no way I can to think of to tell what the issue is here.

Debugging tips:

  • check parent.location.href to make sure you are accessing the window you think you are,
  • check parent.document.getElementId(id) to make sure that you get an element object (as opposed to null or undefined),
  • check parent.document.getElementById(id).tagName to make sure you are using the correct ID (tagName should === "IFRAME")

This line:

parent.getElementById(id).location.reload();

has two problems:

  1. getElementById() is a function of document, but it is being called from parent which is a window object, and
  2. location is a property of a window object. You are trying to access the iframe element's location property, which does not exist. You need a reference to the iframe's window, not its element.

Besides the name method, there are other ways to get the iframe's window object:

  1. document.getElementById('iframeId').contentWindow; // for supported browsers
  2. window.frames["iframeName"]; // assumes name property was set on the iframe
  3. window.frames[i]; // where i is the ordinal for the frame

If changing the src of the iframe element is not working for you, these other fixes might:

parent.document.getElementById(id).contentWindow.location.reload();

or

parent.frames["yourIframeName"].location.reload(); // requires iframe name attribute

or

parent.frames[0].location.reload(); // frames of immediate parent window

or

top.frames[0].location.reload(); // frames of top-most parent window

Caution: If using the name method be careful not to use a common value for name, like "home", for example, as it conflicts with a FireFox function called home() and so Firefox will not automatically create a reference to an iframe's window if it is named home. The most reliable method is probably to use window.frames[] as I believe that has been around for a long time (works in FF / Chrome / Safari / IE6+ (at least))

A more in-depth (but pretty minimal) example follows, tested in Chrome, FF, and IE:

File #1: frametest.html (the parent window)

<!DOCTYPE html>
<html>
<body>
    <iframe id="frame1Id" name="frame1Name" src="frame1.html"></iframe>
    <iframe id="frame2Id" name="frame2Name" src="frame2.html"></iframe>
</body>
</html>

File #2: frame1.html (frame 1's src)

<!DOCTYPE html>
<html>
<body>
FRAME 1
<script>
    document.body.style.backgroundColor="#ccc";
    setTimeout(function(){document.body.style.backgroundColor="#fff";},100);
    document.write(new Date());
</script>
<input type="button" onclick="parent.document.getElementById('frame2Id').src=parent.document.getElementById('frame2Id').src;" value="Refresh frame 2 by ID"/>
<input type="button" onclick="parent.frame2Name.location.reload();" value="Refresh frame 2 by Name"/>
</body>
</html>

File #3: frame2.html (frame 2's src)

<!DOCTYPE html>
<html>
<body>
FRAME 1
<script>
    document.body.style.backgroundColor="#ccc";
    setTimeout(function(){document.body.style.backgroundColor="#fff";},100);
    document.write(new Date());
</script>
<input type="button" onclick="parent.document.getElementById('frame1Id').src=parent.document.getElementById('frame1Id').src;" value="Refresh frame 2 by ID"/>
<input type="button" onclick="parent.frame1Name.location.reload();" value="Refresh frame 2 by Name"/>
</body>
</html>

This example demonstrates how to define and manipulate iframes by id and by name, and how to affect one iframe from within a different iframe. Depending on browser settings, origin policy may apply, but you already said that your content was all from the same domain so you should be OK there.

like image 57
nothingisnecessary Avatar answered Jan 24 '23 02:01

nothingisnecessary