0

I have a page with multiple iframes. These iframes have unique content to begin with, but all lead to the same success page. From that success page, I want to reload only the specific iframe that is being viewed.

I have tried this, but i get an error.

var ifr=document.getElementsByName(window.frameElement.getAttribute("Name"))[0]; ifr.src=ifr.src;

As you can see, I've used the standard iframe src reload method, but am trying to reference the name of the iframe element by name.

Any ideas how I could fix this?

Tom Bunn
  • 25
  • 4
  • this answer might help you. https://stackoverflow.com/questions/86428/what-s-the-best-way-to-reload-refresh-an-iframe#answer-86771 – Rakesh Maddala Mar 31 '22 at 06:56

1 Answers1

0

You need to access the parent page's document to be able to get the <iframe>, in the current frame's document, that element isn't accessible.

If the page in the iframe is from the same domain as the main page, then you can find that parent document through window.parent.document, but this will work only if both pages share the same origin.

So the best might be to embrace directly a more bullet-proof solution that will work even in cross-origin iframes: use the postMessage API.
From your iframe you can send a message to the parent window letting it know that it's ready to be reloaded. On the parent page, you'd listen for such message and reload the source iframe. Since this event receives the source WindowProxy object that is also available as iframe.contentWindow, we don't even need to set a name attribute anymore:

window.addEventListener("message", (evt) => {
  if (evt.data === "confirmation" /* && evt.origin === theURL */) {
    // search for the source <iframe>
    const frameElement = [...document.querySelectorAll("iframe")]
      .find((elem) => elem.contentWindow === evt.source);
    if (frameElement) {
      // I use srdoc in this Snippet but you'd use .src
      frameElement.srcdoc = frameElement.srcdoc;
    }
  }
});
<iframe srcdoc="
  <h1>first page</h1>
  <a>go to confirmation page</a>
  <script>
    // the content of the second iframe
    const confirmContent = `<!DOCTYPE html>
    <h1>confirmed</h1>
    <h2>You will be redirected in a few seconds</h2>
    <script>
      setTimeout(() => {
        parent.postMessage('confirmation', '*');
      }, 2000);
    <\/script>`;    
    document.querySelector('a').href = 'data:text/html,' + encodeURIComponent(confirmContent);
  </script>
"></iframe>

To clarify a bit this example since StackSnippets force us to use some weird workarounds, you'd have in the parent page:

<iframe src="frame.html"></iframe>
<script>
window.addEventListener("message", (evt) => {
  if (evt.data === "confirmation" /* && evt.origin === theURL */) {
    // search for the source <iframe>
    const frameElement = [...document.querySelectorAll("iframe")]
      .find((elem) => elem.contentWindow === evt.source);
    if (frameElement) {
      frameElement.src = frameElement.src;
    }
  }
});
</script>

Then in iframe.html:

<h1>first page</h1>
<a href="https://example.com/confirmation.html">go to confirmation page</a>

and in confirmation.html:

<h1>confirmed</h1>
<h2>You will be redirected in a few seconds</h2>
<script>
  setTimeout(() => {
    parent.postMessage("confirmation", "*");
  }, 2000);
<\/script>
Kaiido
  • 123,334
  • 13
  • 219
  • 285