views:

286

answers:

1

It seems that I must be missing something completely elementary. What I’m trying to achieve looks like quite a common case, and so it makes me wonder why there is no straightforward way.

The problem is that I would like to refresh the current page from JavaScript and simultaneously land on a #section. If I do simply:

document.location.href = document.location.href + "#section";

all browsers I tested just scroll to that #section (no reload). It makes sense in a way. Just for completeness, if I do

document.location.assign(document.location.href + "#section");

it does the same thing (not surprisingly; it boils down internally to the same function for sure). Finally, the document object seems to have also the document.reload() function which takes an optional boolean argument specifying whether I want to force the reload, but obviously, it does not allow to specify the #section. The only way I could find (using these methods) was the following combination:

document.location.assign(document.location.href + "#section");
document.location.reload();

But it is not ideal, because as you have probably guessed, it scrolls and then reloads which causes the browser to actually scroll three times in the end.

I know that there are ways around it: server side redirect or adding some unique random query string parameter, but it seems strange that there is no simple way.

+1  A: 

That is the "hash" value of the location object. You need to set it like this...

location.hash = "#section";

If that does not work consistently, you might want to consider using a scrollToElement function...

function scrollToElement(elem) {
    if(typeof elem == 'string') elem = document.getElementById(elemId);
    var top = 0;

    if(elem) {
        if(elem.offsetParent) {
            top = elem.offsetTop;

            while(elem = elem.offsetParent) {
                top += elem.offsetTop;
            }
        }

        window.scrollTo(0, top);
    }

}

If you absolutely need a page reload (not sure why you ever would), try opening a window in itself...

window.open(location.href + '#section', '_top');

Or try replace...

location.replace(location.href + '#section');
Josh Stodola
Thank you. I did not think of window.open(), but I just tested it, and if I’m not mistaken, it behaves the same way. It just scrolls and does not trigger a full reload.
Jan Zich
I know that it perhaps sounds a bit fishy (forcing a reaload), and it perhaps is and I’ll change it later. But it’s for the first version of the application I’m working on and the priority is to have some complete working version, and then polish the details. But in any case, I was surprised that something which I expected to be easily done in JavaScript is not that easy after all.
Jan Zich