Setting location.hash in frames
Asked Answered
L

7

6

I am using ajax to update the location of a page in a frame. But when setting the location of the hash (on Chrome and some versions of IE (5.5) specifically, but occasionally on IE7) the page is being reloaded.

The following html demonstrates the problem.

the main frame.... frame.html is

<html><head>
<frameset rows="*">
<frame src=sethash.html frameborder=0 scrolling=auto name=somebody>
</frameset>
</head></html>

the sethash.html page is .

<html><head>
<script language=JavaScript>
var Count = 0;
function sethash()
{  
  top.document.location.hash = "hash" + Count;  
  Count++;
}
</script>
</head>
<body onload="alert('loaded')">
<h1>Hello</h1>
<input type='button' onClick='sethash()' value='Set Hash'>
</body>
</html>`

On most browsers loading the frame.html will show the loaded alert once when the page is loaded. Then when the set hash button is pressed the url will be changed but the hash the loaded alert will not show again. On chrome and some versions of I.E

Microsoft report possibly the same problem with Internet Explorer 5.5 link text

I can't use the microsoft suggested solution, which is to capture the event and not fire it, but just scroll into view, as am using set the top.location.hash as part of the onLoad event.

Laudianism answered 13/3, 2009 at 14:25 Comment(0)
S
6

Webkit (and by extension, Chrome) behave strangely with location.hash. There are a few open bugs about it, the most relevant is probably this one: https://bugs.webkit.org/show_bug.cgi?id=24578 that documents your problem of having the page refresh when location.hash is changed. It looks like your best option right now is to cross your fingers and hope that it gets promptly fixed.

I can't reproduce the bug in IE7 though, and you're the first person in ages I've seen that supports IE5.5 so I can't really help you there ;)

Sinew answered 3/4, 2009 at 0:54 Comment(0)
W
3

You could also use HTML5 history.pushState() to change hash without reloading page in Chrome. Something like this:

// frameset hash change function
function changeHash(win, hash) {
    if(history.pushState) {
        win.history.replaceState(null, win.document.title, '#'+hash);
    } else {
        win.location.hash = hash;
    }
}

In the first argument you need to pass frameset top window.

Wordless answered 7/2, 2012 at 7:54 Comment(1)
This works. Small note: Chrome show a flicker in the favicon and stop/refresh button, which looks kind of ugly.Superorder
B
2

I was having this problem as well. My situation allowed me to create a window unbind event that set the hash with the value I wanted it too as the user browser to the next page or refreshed. This worked for me, but not sure it will work for you.

With jquery, I did:

if($.browser.webkit){
    $(window).unload(function() {
        top.window.location.hash = hash_value;
    });
}else{
    top.window.location.hash = hash_value;
}

Technically you don't need to do the webkit check, but I thought for people who use firefox, it might be nice to see the correct hash value before they refresh the frameset.

-Jacob

Berrios answered 30/1, 2010 at 22:45 Comment(0)
P
2

for chrome and safari, you need to use window.location.href to get the hash working rather than window.location.hash

see code below

function loadHash(varHash)
{
  if(varHash != undefined) {
    var strBrowser = navigator.userAgent.toLowerCase();

    if (strBrowser.indexOf('chrome') > 0 || strBrowser.indexOf('safari') > 0) {
        this.location.href = "#" + varHash;
    }
    else {
        this.window.location.hash = "#" + varHash;
    }
  }
}
Pollak answered 5/4, 2011 at 13:4 Comment(0)
S
1

I have a workaround and it involves a full-page table with embedded iframes. I replaced my frameset with a table that takes up 100% height and 100% width and has two rows. Then, in each of the table cells I put an iframe that takes up 100% height and width for each cell. This, essentially, mimics a frameset without BEING a frameset. Best of all, no reload on hash change!

Here's my old code:

<html>
<head>
<title>Title</title>
</head>
<frameset rows="48,*" frameborder="yes" border="1">
    <frame name="header" noresize="noresize" scrolling="no" src="http://header" target="_top">
    <frame name="main" src="http://body" target="_top">
    <noframes>
    <body>
    <p>This page uses frames, but your browser doesn&#39;t support them.</p>
    </body>
    </noframes>
</frameset>
</html>

...and here's my new code:

<html>
<head>
<title>Title</title>
<style type="text/css">
body { margin: 0px; padding: 0px; border: none; height: 100%; }
table { height:100%; width:100% }
td { padding: 0px; margin: 0px; border: none; }
td.header { height: 48px; background-color: black; }
td.body { background-color: silver; }
iframe.header { border: none; width: 100%; height: 100%; }
iframe.body { border: none; width: 100%; height: 100%; }
</style>
</head>
<body>
<table cellpadding="0" cellspacing="0">
  <tr><td class="header"><iframe class="header" src="http://header" target="_top" scrolling="no"></iframe></td></tr>
  <tr><td class="body"><iframe class="body" src="http://body" scrolling="no"></iframe></td></tr>
</table>
</body>
</html>

Hope this helps.

Strawberry answered 27/5, 2011 at 19:3 Comment(0)
D
0

Have you tried creating hidden links to the hashes and firing the click even on them?

Decadence answered 3/4, 2009 at 21:43 Comment(0)
L
0

What about doing location.href = '#yourhash'; Maybe it bypasses the bug.

Lacedaemonian answered 29/4, 2009 at 2:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.