7

I have 2 simple html pages: parent and child. Parent stores child inside the iframe.
Parent.html:

<html>
<head></head>
<body>

<input type="text" id="text" />
<input type="button" value="change hash" onclick="javascript:changeHash()" />

<iframe src="Child.html"></iframe>

<script type="text/javascript">
    function changeHash () {
        window.location.hash = document.getElementById('text').value;
    }
</script>

</body>
</html>

And Child.html:

<html>
<head></head>
<body>

<input type="button" value="go back" onclick="javascript:goBack()" />

<script type="text/javascript">
    function goBack () {
        this.history.back();
    }
</script>

</body>
</html>

I use change hash button to add several hashes to history. And when I press go back button inside the iframe - the hash of the Parent page is changed. And seems that this is behavior by the spec.

So the question is: is it possible to prevent propagation of going back from the iframe to it's parent page? So I would like the iframe not to change the parent's history/hash.

Note: the same behavior is for go function (actually, go(-1) is the same as back()).

Kiril
  • 2,935
  • 1
  • 33
  • 41
  • if the iframe can communicate with parent, can't you just restore the lost hash? it'll be so quick no one will notice. – vsync Aug 03 '14 at 00:12
  • @vsync, the problem is that the outer page hash `hashchange` event subscription and this is how the navigation is done. So the app will navigate user back. – Kiril Aug 03 '14 at 08:44
  • Try to implement a `history navigation` stack on your own (using localStorage for example) and change your `goBack` function to not rely on `window.history`. – php-dev Aug 05 '14 at 12:40
  • @php-dev, of course, this is a solution. But it's just an interesting behavior and now it's just a kind of "challenge". – Kiril Aug 05 '14 at 12:47

1 Answers1

3

I think it's impossible to do this witout the use of a framework, but I have a solution that may (partially) solve this problem.

First, I thought of changing the object history and redefining it, but it's impossible since it's a property inside the window which is not writable. but we can redefine the functions inside history.

This is what led me to redefine the function back() and instead of letting the history object doing his job, we have to find the previous url and changing the location of the document (child).

In you're Child.html, redefine the function back() like this :

history.back = function ()
{
    document.location = document.referrer;
}

The problem we have in this function, is that once the parent document is loaded, and the iframe (child) is loaded too, the document.referrer of the child returns the url of the parent

So, before changing the document.location, let's test if the document.referrer is different from parent's url (witout anchor)

history.back = function ()
{
    var url = window.parent.document.location.href.split("#")[0];
    if(document.referrer!=url)
        document.location = document.referrer;
}

Finally, this is the solution I found, and unfortunately it has a problem, is that you can't redefine the function forward() that allows you to go to the next url, it's impossible to find the next url, and document.referrer returns the url of the page you came from, it could be the previous page or the next page. but still you can navigate inside the iframe witout changing the parent location.

Community
  • 1
  • 1
Khalid
  • 4,730
  • 5
  • 27
  • 50
  • thanks for your response! But it will work only for back. There's one more ability to go back - `history.go(-1)`. Actually, it's possible to override `go` function, but it could navigate 2,3,... steps back. In case of 2+ steps back `document.referrer` won't work. – Kiril Aug 04 '14 at 08:00
  • 1
    yes you're right, but don't forget that `history.go` changes the url of the parent window – Khalid Aug 04 '14 at 12:40