Reload an IFRAME without adding to the history
Asked Answered
S

11

77

I'm changing an IFRAME's src in order to reload it, its working fine and firing the onload event when its HTML loads.

But it adds an entry to the history, which I don't want. Is there any way to reload an IFRAME and yet not affect the history?

Swum answered 4/5, 2009 at 18:45 Comment(2)
I'm guessing the problem is the back button will actually cycle through the iframe before actually going to the previous page.Complimentary
Whatever it does, I don't want any additions to the history, or is there a way I can delete the latest history entry??Swum
T
39

You can use javascript location.replace:

window.location.replace('...html');

Replace the current document with the one at the provided URL. The difference from the assign() method is that after using replace() the current page will not be saved in session history, meaning the user won't be able to use the Back button to navigate to it.

Teem answered 4/5, 2009 at 18:50 Comment(8)
Would'nt this target the page itself? I only want to reload the IFRAME and I've no control over the scripts running inside the loaded document.Swum
Just replace "window" with a reference to your iframe.Efik
Why is it not that simple? var ifr = document.getElementById("iframeId"); ifr.location.replace(ifr.src);Hickman
This doesn't work. In Firefox it errors with "ifr.location is undefined"Dogooder
Try using window.frames['frame_name'].locationFiner
You can also use iframe.contentWindow.location.replace(href);Intercontinental
This way you have to check to make sure the compatibility to different browsers!Detain
Using the window.frames solution ChrisD mentions gave me a errors in Google Chrome, Kyle's solution solved this for me.Mellisamellisent
A
80

Using replace() is only an option with your own domain iframes. It fails to work on remote sites (eg: a twitter button) and requires some browser-specific knowledge to reliably access the child window.

Instead, just remove the iframe element and construct a new one in the same spot. History items are only created when you modify the src attribute after it is in the DOM, so make sure to set it before the append.

Edit: JDandChips rightly mentions that you can remove from DOM, modifiy, and re-append. Constructing fresh is not required.

Ampliate answered 30/12, 2011 at 16:27 Comment(5)
While this answer is 2 years newer than the accepted answer, it is the correct way to change an iframe URL/src without adding to the browser's history. Any other combination of window.frames[frameName].location and/or history.replaceState won't work in an iframe for security reasons. Even on the same domain (as I just found out).Goldshlag
This is the best working answer I have tried. Solved my problem.Maynardmayne
The solution was this one! I needed to create the iframe so the history remains intact.Blythebm
Great answer. I was trying to add vimeo embeded video with iframe and angular, something like this: <div ng-repeat="item in ct.items"><iframe src="{{item.url}}"></iframe></div>. It happens that before the angular sets the iframe url, the html tried to load the iframe with the wrong url like {{item.url}}, the result is that the iframe had it's src changed, causing the browser history problem! The solution was creating the iframe later, with jquery, after angular rendered everything.Indies
Does this issue also occur if the url is changed from inside the iframe itself (like if the user clicks or J.S. redirects to a 2nd page inside the iframe)? I dont change the iframe src directly via DOM. Ex: I have an AdobeEsign page embedded in an iframe in my SPA, that redirects to a Thank You page in the same iframe (then the Thank You page send a windows.postmessage back to my main frame so I can close the iframe)... but clicking the Browser back button in my SPA at this point seems like its wanting to 'leave the page' (my window.beforeunload event fires as the user is leaving the SPA).Artemis
T
39

You can use javascript location.replace:

window.location.replace('...html');

Replace the current document with the one at the provided URL. The difference from the assign() method is that after using replace() the current page will not be saved in session history, meaning the user won't be able to use the Back button to navigate to it.

Teem answered 4/5, 2009 at 18:50 Comment(8)
Would'nt this target the page itself? I only want to reload the IFRAME and I've no control over the scripts running inside the loaded document.Swum
Just replace "window" with a reference to your iframe.Efik
Why is it not that simple? var ifr = document.getElementById("iframeId"); ifr.location.replace(ifr.src);Hickman
This doesn't work. In Firefox it errors with "ifr.location is undefined"Dogooder
Try using window.frames['frame_name'].locationFiner
You can also use iframe.contentWindow.location.replace(href);Intercontinental
This way you have to check to make sure the compatibility to different browsers!Detain
Using the window.frames solution ChrisD mentions gave me a errors in Google Chrome, Kyle's solution solved this for me.Mellisamellisent
F
27

Like Greg said above, the .replace() function is how to do this. I can't seem to figure out how to reply to his answer*, but the trick is to reference the iFrames contentWindow property.

var ifr = document.getElementById("iframeId");
ifr.contentWindow.location.replace("newLocation.html"); 

*Just learned I need more reputation to comment on an answer.

Forwent answered 19/1, 2011 at 15:5 Comment(0)
S
15

An alternative method to recreating the iframe would be to remove the iframe from the DOM, change the src and then re add it.

In many ways this is similar to the replace() suggestion, but I had some issues when I tried that approach with History.js and managing states manually.

var container = iframe.parent();

iframe.remove();
iframe.attr('src', 'about:blank');

container.append(iframe);
Scandal answered 18/8, 2014 at 14:39 Comment(2)
I really like this: it turned out to be way easier than creating a new iframe because you don't need to copy over all the properties to the new iframe (id, size, style classes, ...)Graecize
Great find. This solution worked for me in the case of loading iframe content in a Bootstrap modal window. When the modal is closed, use the callback to remove it, and add it back. Fixes the back button issue. $(modal).one('hidden.bs.modal', function() { $(modal_iframe).attr('src', 'about:blank').addClass('d-none'); var modalParent = $(modal_iframe).parent(); $(modal_iframe).remove(); $(modalParent).append($(modal_iframe)); });Trix
N
10

One solution is to use the object tag rather than the iframe tag.

Replacing this:

<iframe src="http://yourpage"/>

By this:

<object type="text/html" data="http://yourpage"/>

will allow you to update the data attribute without affecting the history. This is useful if you use a declarative framework such as React.js where you are not supposed to do any imperative command to update the DOM.

More details on differences between iframe and object: Use of Iframe or Object tag to embed web pages in another

Nightstick answered 29/9, 2015 at 22:6 Comment(2)
Agreed great answer @Nightstick this helped me immensely with Angular2 and not having the iframe src changes trigger history updates.Astaire
This doesn't work for me. I'm in Chrome. Even destroying the iframe and replacing it with an object still causes the darn browser history state (which makes no sense because the destroyed object will never get it's content back). Grrrrrrrrr.Crowther
D
5

Try to use this function to replace old iframe with new iframe which is copied from old one:

function setIFrameSrc(idFrame, url) {
    var originalFrame = document.getElementById(idFrame);
    var newFrame = document.createElement("iframe");
    newFrame.id = originalFrame.getAttribute("id");
    newFrame.width = originalFrame.getAttribute("width");
    newFrame.height = originalFrame.getAttribute("height");
    newFrame.src = url;    
    var parent = originalFrame.parentNode;
    parent.replaceChild(newFrame, originalFrame);
}

Use it like this:

setIFrameSrc("idframe", "test.html");

This way will not add URL of iframe to browser history.

Detain answered 25/2, 2014 at 17:25 Comment(0)
F
2

JDandChips answer worked for me on a cross origin iframe (youtube), here it is in vanilla JS (without JQuery):

const container = iframe.parentElement;

container.removeChild(iframe);

iframe.setAttribute('src', 'about:blank');

container.appendChild(iframe);
Fullfaced answered 23/5, 2019 at 11:27 Comment(0)
B
1

Use the replace method to bypass the addition of the iframe's URL to history:

HTML:

<iframe id="myIframe" width="100%" height="400" src="#"></iframe>

JavaScript:

var ifr = document.getElementById('mIframe')
if (ifr) {
  ifr.contentWindow.location.replace('http://www.blabla.com')
}
Bogbean answered 8/8, 2017 at 13:35 Comment(1)
What is the string/URL sent to replace?Germin
D
0

The most simple and fast loading solution
Use window.location.replace to not update the history when loading the page or the frame.

For links it looks like this:

<a href="#" onclick="YourTarget.location.replace ('http://www.YourPage.com');">
The targeted Link</a>

or

<a href="javascript:YourTarget.location.replace ('http://www.YourPage.com');">
The targeted Link</a>



But if you want it not to act from link but to act automatically when loading the frame then from the iframe you should put this in the iframe file body section:

onload="window.location.replace ('http://www.YourPage.com');"


If for some reason the onload does not load in the iframe then put your target frame name instead of window in the syntax like this:

onload="YourTarget.location.replace ('http://www.YourPage.com');"



NOTE: For this script all onclick, onmouseover, onmouseout , onload and href="javascript:" will work.

Dysprosium answered 4/1, 2017 at 19:57 Comment(0)
J
0

@JDandChips has a great answer above, but the syntax should be updated from parent() to parentElement:

var container = iframe.parentElement;

iframe.remove();
iframe.attr('src', 'about:blank');

container.append(iframe);
Jiggered answered 29/10, 2019 at 16:10 Comment(1)
Welcome to StackOverflow! If an answer is largely correct and only really needs minor updates, you should suggest an edit to the answer rather than posting a new one yourself. It'll get you a badge if your suggestion gets accepted :)Method
D
0

There is also a nice solutions by setting the key attribute of the iframe to prevent the iframe from adding to the history.

Especially if working with frameworks like...

react

<iframe key={contentId} src={`embedded/content/${contentId}`} />

vue

<iframe :key="contentId" :src="src" />

A very detailed explentation can be found here:

https://www.aleksandrhovhannisyan.com/blog/react-iframes-back-navigation-bug/

Dripdry answered 12/10, 2023 at 8:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.