90

Can someone show me what I'm doing wrong? I need my page to refresh after a certain period of time, but it refreshes to the top of the page, I need it to not change the page location! So this is what I have now, which is not working. Is it the meta tags? Here is what I have which still doesn't refresh. Must be doing something wrong?

Here is what I originally had...

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="refresh" content="72">
        <meta http-equiv="Pragma" CONTENT="no-cache">
        <meta http-equiv="Expires" CONTENT="-1">

        <style type="text/css">
        body
        { 
            background-image: url('../Images/Black-BackGround.gif');
            background-repeat: repeat;
        }
        </style>
    </head>

    <script type="text/javascript">

    function saveScrollPositions(theForm) {
        if(theForm) {
            var scrolly = typeof window.pageYOffset != 'undefined' ? window.pageYOffset
                                                   : document.documentElement.scrollTop;
            var scrollx = typeof window.pageXOffset != 'undefined' ? window.pageXOffset
                                                  : document.documentElement.scrollLeft;
            theForm.scrollx.value = scrollx;
            theForm.scrolly.value = scrolly;
        }
    }
    </script>

 <form action="enroll.php" name="enrollment" method="post" onsubmit="return saveScrollPositions (this);">
  <input type="hidden" name="scrollx" id="scrollx" value="0" />
  <input type="hidden" name="scrolly" id="scrolly" value="0" />

  <STYLE type="text/css">
   #Nav a{ position:relative; display:block; text-decoration: none; color:Black; }
   Body td{font-Family: Arial; font-size: 12px; }
  </style>

After reading some of the initial answers I've changed it to this...

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

<style type="text/css">
body
{ 
    background-image: url('../Images/Black-BackGround.gif');
    background-repeat: repeat;
}
</style>
</head>


<script>
function refreshPage () {
    var page_y = $( document ).scrollTop();
    window.location.href = window.location.href + '?page_y=' + page_y;
}
window.onload = function () {
    setTimeout(refreshPage, 35000);
    if ( window.location.href.indexOf('page_y') != -1 ) {
        var match = window.location.href.split('?')[1].split("&")[0].split("=");
        $('html, body').scrollTop( match[1] );
    }
}
</script>

<STYLE type="text/css">
#Nav a{ position:relative; display:block; text-decoration: none; color:black; }
Body td{font-Family: Arial; font-size: 12px; }
</style>
Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
chriswiec
  • 1,101
  • 1
  • 10
  • 18

10 Answers10

71

this will do the magic

    <script>
        document.addEventListener("DOMContentLoaded", function(event) { 
            var scrollpos = localStorage.getItem('scrollpos');
            if (scrollpos) window.scrollTo(0, scrollpos);
        });

        window.onbeforeunload = function(e) {
            localStorage.setItem('scrollpos', window.scrollY);
        };
    </script>
  • 12
    Very good and simple solution. I made a few changes. Browsers will still store this data even after the browser is closed. I replaced localStorage with sessionStorage and cleared it using sessionStorage.removeItem('scrollpos') after the scroll position was set. This insures scroll position is cleared once the browser is closed. I posted modified code as separate answer. – Ben Jul 13 '20 at 18:16
  • 1
    If you want to keep the scroll position of an element like a div, you can use this same technique to set the element's `scrollTop` attribute. – Joe Nov 06 '22 at 16:01
55

document.location.reload() stores the position, see in the docs.

Add additional true parameter to force reload, but without restoring the position.

document.location.reload(true)

MDN docs:

The forcedReload flag changes how some browsers handle the user's scroll position. Usually reload() restores the scroll position afterward, but forced mode can scroll back to the top of the page, as if window.scrollY === 0.

Synox
  • 1,148
  • 2
  • 17
  • 38
powtac
  • 40,542
  • 28
  • 115
  • 170
  • 2
    This is mentioned on MDN now. – trysis Apr 01 '16 at 14:48
  • 2
    @trysis Where? Can't see it on https://developer.mozilla.org/en-US/docs/Web/API/Location/reload$compare?locale=en-US&to=788646&from=471047 – powtac Apr 01 '16 at 17:04
  • 2
    It is on the page linked to in your answer. They call it `forcedReload`. – trysis Apr 01 '16 at 18:20
  • 2
    The docs say "while in forced mode (when parameter is set to true) the new DOM gets loaded with scrollTop == 0." - This does not sound like it keeps the scroll position. I have not have time to test it, so I might be missing something... – Daryn Apr 21 '17 at 07:28
  • 4
    Only works in Chrome for me, neither latest FF or Edge keeps the scroll position, instead scrolls to top – g.pickardou Sep 27 '18 at 09:18
  • 2
    Internet Explorer does not save the position. I used @zingle-dingle 's answer – Steve Scott Nov 07 '18 at 16:52
  • I'm not seeing the block quote or the parameter described in the linked MDN page. Has this feature been deprecated, or was the documentation incorrect? – Jake Worth Jul 29 '21 at 14:53
  • Helllo. Can anyone tell me if i can do this on any website i visit via chrome? – vickyace Nov 11 '21 at 16:40
16

If you don't want to use local storage then you could attach the y position of the page to the url and grab it with js on load and set the page offset to the get param you passed in, i.e.:

//code to refresh the page
var page_y = $( document ).scrollTop();
window.location.href = window.location.href + '?page_y=' + page_y;


//code to handle setting page offset on load
$(function() {
    if ( window.location.href.indexOf( 'page_y' ) != -1 ) {
        //gets the number from end of url
        var match = window.location.href.split('?')[1].match( /\d+$/ );
        var page_y = match[0];

        //sets the page offset 
        $( 'html, body' ).scrollTop( page_y );
    }
});
CaptainBli
  • 4,121
  • 4
  • 39
  • 58
kkemple
  • 982
  • 5
  • 9
  • so keep the meta tags and replace the function save scroll position in between scrupt tags? – chriswiec Jul 15 '13 at 02:28
  • Well add: `//code to refresh the page var page_y = $( document ).scrollTop(); window.location.href = window.location.href + '?page_y=' + page_y;` for the save function. – Shawn31313 Jul 15 '13 at 02:29
  • I edited the code so that it would actual work. JavaScript is object oriented. @kkemple was using an indexOf function which doesn't exists. And there was stuff wrong in the `match` variable too. The edit just has to get accepted. – Shawn31313 Jul 15 '13 at 02:30
  • does it look right in the question now I edited it to look like what I think you were saying? – chriswiec Jul 15 '13 at 02:34
  • Can you email me chrisw.iec@me.com So I can better understand, I'm two weeks into my first html scripting. – chriswiec Jul 15 '13 at 02:39
  • @chrisw.iec I added a new answer. – Shawn31313 Jul 15 '13 at 03:04
  • @Shawn31313 i don't see any way to accept an edit? new to the site...and you are correct wrote this in a hurry, there is indexOf but it should read `if( window.location.href.indexOf( 'page_y' ) !== -1 )` and the match variable is regex, here is the link with test case for my expression [regexr](http://regexr.com?35itm), it matches any length of numbers at the end of a string, so the value of the page_y param. – kkemple Jul 15 '13 at 04:12
  • @Shawn31313 your edit was rejected, but i updated the part of the incorrect indexOf, however i left the part about the regex match as that is a correct regex and would have the same effect as your suggested change – kkemple Jul 15 '13 at 04:18
  • 1
    @kkemple but that also matches: ?sadjsaid332 or ?2332 ... plus, i wasn't referring to the RegExp..i was talking about `.split['?']` << thats incorrect. – Shawn31313 Jul 15 '13 at 04:22
  • @Shawn31313, ah yeah good catch, thats what i get for answering from my phone, and no that regex only matches digits, and double split method could be anything after the =, check the regex test i linked to, it will only match a digit sequence at the end of the string – kkemple Jul 15 '13 at 09:22
  • So what should the code look like from to – chriswiec Jul 15 '13 at 11:59
15

I modified Sanoj Dushmantha's answer to use sessionStorage instead of localStorage. However, despite the documentation, browsers will still store this data even after the browser is closed. To fix this issue, I am removing the scroll position after it is reset.

<script>
    document.addEventListener("DOMContentLoaded", function (event) {
        var scrollpos = sessionStorage.getItem('scrollpos');
        if (scrollpos) {
            window.scrollTo(0, scrollpos);
            sessionStorage.removeItem('scrollpos');
        }
    });

    window.addEventListener("beforeunload", function (e) {
        sessionStorage.setItem('scrollpos', window.scrollY);
    });
</script>
Ben
  • 1,853
  • 19
  • 20
  • 1
    Very useful, thanks! I have two question, while trying to maintain the scrollPosition, is it possible to avoid seeing little transition animation on each load/refresh? Also, will it share between tabs? How to handle sessions in multiple tabs? Does creating unique key name for each page gives any significant impact to web performance? – NcXNaV Jul 29 '21 at 06:11
9

UPDATE

You can use document.location.reload(true) as mentioned below instead of the forced trick below.

Replace your HTML with this:

<!DOCTYPE html>
<html>
    <head>
        <style type="text/css">
            body { 
                background-image: url('../Images/Black-BackGround.gif');
                background-repeat: repeat;
            }
            body td {
               font-Family: Arial; 
               font-size: 12px; 
            }
            #Nav a { 
                position:relative; 
                display:block; 
                text-decoration: none; 
                color:black; 
            }
        </style>
        <script type="text/javascript">
            function refreshPage () {
                var page_y = document.getElementsByTagName("body")[0].scrollTop;
                window.location.href = window.location.href.split('?')[0] + '?page_y=' + page_y;
            }
            window.onload = function () {
                setTimeout(refreshPage, 35000);
                if ( window.location.href.indexOf('page_y') != -1 ) {
                    var match = window.location.href.split('?')[1].split("&")[0].split("=");
                    document.getElementsByTagName("body")[0].scrollTop = match[1];
                }
            }
        </script>
    </head>
    <body><!-- BODY CONTENT HERE --></body>
</html>
Shawn31313
  • 5,978
  • 4
  • 38
  • 80
  • 1
    Did not work on firefox (scrollTop is always zero) so I used [this](http://mrcoles.com/blog/scroll-sneak-maintain-position-between-page-loads/) – Sanjay Sahani Aug 29 '14 at 12:55
  • 1
    I could not get this to work in IE 11. I added a bunch of these in the body: `sadsad
    ` but when I clicked the link I got to the top of the page.
    – Stig Eide May 08 '15 at 11:11
7

This might be useful for refreshing also. But if you want to keep track of position on the page before you click on a same position.. The following code will help.

Also added a data-confirm for prompting the user if they really want to do that..

Note: I'm using jQuery and js-cookie.js to store cookie info.

$(document).ready(function() {
    // make all links with data-confirm prompt the user first.
    $('[data-confirm]').on("click", function (e) {
        e.preventDefault();
        var msg = $(this).data("confirm");
        if(confirm(msg)==true) {
            var url = this.href;
            if(url.length>0) window.location = url;
            return true;
        }
        return false;
    });

    // on certain links save the scroll postion.
    $('.saveScrollPostion').on("click", function (e) {
        e.preventDefault();
        var currentYOffset = window.pageYOffset;  // save current page postion.
        Cookies.set('jumpToScrollPostion', currentYOffset);
        if(!$(this).attr("data-confirm")) {  // if there is no data-confirm on this link then trigger the click. else we have issues.
            var url = this.href;
            window.location = url;
            //$(this).trigger('click');  // continue with click event.
        }
    });

    // check if we should jump to postion.
    if(Cookies.get('jumpToScrollPostion') !== "undefined") {
        var jumpTo = Cookies.get('jumpToScrollPostion');
        window.scrollTo(0, jumpTo);
        Cookies.remove('jumpToScrollPostion');  // and delete cookie so we don't jump again.
    }
});

A example of using it like this.

<a href='gotopage.html' class='saveScrollPostion' data-confirm='Are you sure?'>Goto what the heck</a>
zingle-dingle
  • 1,681
  • 16
  • 16
  • This answer is a little bloated but I liked it anyway. I was able to do it with the cookie check and these two lines: var currentYOffset = window.pageYOffset; // save current page postion. Cookies.set('jumpToScrollPostion', currentYOffset); – Steve Scott Nov 07 '18 at 16:50
7

Thanks Sanoj, that worked for me.
However iOS does not support "onbeforeunload" on iPhone. Workaround for me was to set localStorage with js:

<button onclick="myFunction()">Click me</button>

<script>
document.addEventListener("DOMContentLoaded", function(event) { 
            var scrollpos = localStorage.getItem('scrollpos');
            if (scrollpos) window.scrollTo(0, scrollpos);
        });
function myFunction() {
  localStorage.setItem('scrollpos', window.scrollY);
  location.reload(); 
}
</script>
Terry m
  • 71
  • 1
  • 1
3

I found a really simple solution to this. Just add an ID link as a separate parameter in the links HREF tag

<a class="page-link" href="{{ url_for('events.home', page=page_num) }}, #past_events">

that links to the top of the div that I want to stay in focus.

1

If you need to navigate to a page with a certain scroll position instead of reloading it, mark an element with an id:

<h1 id="success">Kontakt</h1>

and redirect to the url from js:

window.location.href = '/contact#success'

or from html (@Chris' answer):

<a href="/contact#success"></a>
Artur Müller Romanov
  • 4,417
  • 10
  • 73
  • 132
0

This was the easiest code I've ever had to write.

NEVER use Page.MaintainScrollPositionOnPostBack = True, it is completely useless

This is all the script you need to maintain position. Add this to any page or to the master if you are using master pages.

<script type="text/javascript">

    function setScreen() {
        var yScreen = localStorage.getItem("yPos");
        window.scrollTo(0, yScreen);
    }
    function setScroll() {
        var yScroll = window.pageYOffset;
        localStorage.setItem("yPos", yScroll);
    }
    function clearScreen() {
        localStorage.setItem("yPos", 0);
        window.scrollTo(0, 0);
    }

</script>

Add onscroll="setScroll()" onload="setScreen()" to the body tag

<body onscroll="setScroll()" onload="setScreen()">

To reset scroll when a user returns to your site the local storage needs to be reset

Add this to the Default.aspx page and then redirect user to any page you want.

<script type="text/javascript">

    function resetScroll() {
        localStorage.setItem("yPos", 0);
    location.replace("somepage.aspx")
        }
    }

</script>

Add onload="resetScroll()" to the body tag of that page.

<body onload="resetScroll()">

This took me about 2 hours to write, debug and publish.