Maintain vertical scroll position

This post describes how to maintain vertical scroll position after form submission or clicking on link. Script will read vertical scroll position and append scroll value to URL. After page is loaded, JavaScript function will search for scroll parameter in URL and set the scroll position.

Demo first. Please try to scroll a bit down and click on redips.scroll() link. Reloaded page should stay at the same vertical position. VoilĂ ! And the source:

// define container
var redips = {};

// append scroll parameter to URL or return scroll value
redips.scroll = function (url) {
    let scroll, q;
    // DOM compliant
    if (document.body && document.body.scrollTop) {
        scroll = document.body.scrollTop;
    }
    // old - Netscape compliant
    else if (typeof (window.pageYOffset) === 'number') {
        scroll = window.pageYOffset;
    }
    // very very old - IE6 standards compliant mode
    else if (document.documentElement && document.documentElement.scrollTop) {
        scroll = document.documentElement.scrollTop;
    }
    // when vertical scroll bar is on the top
    else {
        scroll = 0;
    }
    // if input parameter does not exist then return scroll value
    if (url === undefined) {
        return scroll;
    }
    // else append scroll parameter to URL
    else {
        // set "?" or "&" before scroll parameter
        q = url.indexOf('?') === -1 ? '?' : '&';
        // load page with scroll position parameter
        window.location.href = url + q + 'scroll=' + scroll;
    }
};

// set scroll position if URL contains scroll=nnn parameter
redips.setScrollOnLoad = function () {
    // get query string parameter with "?"
    let search = window.location.search,
        matches;
    // if query string exists
    if (search) {
        // find scroll parameter in query string
        matches = /scroll=(\d+)/.exec(search);
        // jump to scroll position if scroll parameter exists
        if (matches) {
            window.scrollTo(0, matches[1]);
        }
    }
};

// add onload event listener
if (window.addEventListener) {
    window.addEventListener('load', redips.setScrollOnLoad, false);
}
else if (window.attachEvent) {
    window.attachEvent('onload', redips.setScrollOnLoad);
}

redips.scroll() link shows how to call this page with some parameters and maintain scroll position. After clicking on link, you will see example parameters followed by scroll position parameter. Please try to change scroll value directly in the address line and press enter. Page should take vertical position according to the changed value.

All source code and examples are prepared in redips11.tar.gz package.

41 thoughts on “Maintain vertical scroll position”

  1. Your example with a form uses two PHP scripts. I have a single PHP script that generates a form. When the form is submitted the script calls itself – the variables are POSTed. I know PHP, but not so much javascript. I’ve been able to get the current Y position and pass it to the PHP script. After submission when the script runs, it will display the PHP variable, but I have not been able to figure out how to modify the set_scroll function to read that PHP variable and use it to position the page. Would you mind providing an example or some suggestions? Thanks!

  2. @ken – This demo doesn’t use PHP or any other server side scripts. It’s completely client side solution and server independent. JavaScript setScroll() function is called after page is loaded. Inside that function you will see the code where it searches for scroll parameter and sets vertical scroll position.

    So, when form is posted to the server, it is important to send scroll parameter as well and send it back in URL. This will allow setScroll() to read query string and to return scroll position.

  3. Hey guys awesome script just what i need, however i have a question, when adding the javascript to the link is there a way to hide the ?param1=a&param2=b&param3=c&scroll=942

    so that it displays the original url?

  4. @Lee – After page is loaded, setScroll() should be able to read scroll position from somewhere – for example, it can be hided inside page JavaScript section. This modification will need some server side tasks to read scroll position and to dynamically change/generate JavaScript code. Originally, JS code presented on this post reads “scroll” position from URL (window.location.search) and it completely independent from the server side. So answer to your question is “Yes”, it possible to hide, but then you will need to involve server side scripting.

  5. LOL why does most people not add the java start and stop code to the code so we have to fiddle with it millions of times?

  6. You can’t expect a user to click a link just so they can remember the scroll position.

    It’s supposed to remember scroll position while the user is scrolling.

  7. @Benley – I can agree with you, but idea of this JS code is to remember vertical scroll position after user made some action (like click on a link). This was useful for our internal Web application and my intention was to share the code. Yes it’s possible to improve the script and to set onScroll() event listener but I didn’t want to import addition logic and to extend this script. This way, concept should be easy to understand and adjustable for other scenarios.

    Anyway, thank you for your comment.

  8. Hi, thank you very much for your help. Great code. However, I prefer to use:

    // to store the position
    localStorage.setItem("myScroll", scroll);
    
    // to retrieve and use it
    setScroll(parseInt(localStorage.getItem("myScroll")));
    

    Explicitly, for instance in the js page:

    function getScroll(){
        var scroll;
        // Netscape compliant
        if (typeof(window.pageYOffset) === 'number') {
            ...
            ...
    
        localStorage.setItem("myScroll", scroll);
    }
    
    function setScroll(scroll){
        window.scrollTo(0, scroll);
    }
    
    window.onload = function() {
        // your own stuff when onloading
        setScroll(parseInt(localStorage.getItem("myScroll")));
    }
    

    In a php page for instance:

    < input id=”submit1″ type=”submit” name=”submit” value=”Submit” onclick=”getScroll();”>

    Hope it helps.

    Cheers,
    Guy

  9. I am trying to implement this on a site that I am building. the form is a multi-page form, and as you click the button to go to the next page, it’s scrolling to the top of the page even though the form is in an iframe. I don’t have a way of adding an onclick event to the button – do you have a suggestion on what I can do to get this working on mobile devices so the user doesn’t think the form is complete?

    thanks
    robb

  10. @guy – Thank you for “localStorage” trick. Your solution looks simple and efficient.

    @robb – If you send “scroll” parameter in URL, onload event will call setScroll() function and vertical scroll position will be set. Maybe described problem is related to iframe where myScroll() function reads iFrame position and set it to the main page in next step.

    You can set break point in Chrome JS inspector to see what really happens and to read variable values before submitting form in iFrame.

  11. div.scrollbar {
    height: 655px;
    overflow: auto;

    }

    $(function() {
    function newPost() {
    $(“#newpost”).empty().load(“slide/parts/extruderRight1.php”);
    }
    var res = setInterval(newPost, 30000);
    });

    To Do List

    <?php foreach($news as $item):
    $fdate=date('Y-m-d H:i:s');

    $a=$item["person6"];
    $action1=$item["person65"];

    echo '’;

    $comname=$item[“comname”];

    $datetime1 = new DateTime();

    $datetime2 = new DateTime($a);
    $interval = $datetime1->diff($datetime2);
    $elapsed = $interval->format(‘%i’);

    $start_date = new DateTime();
    $since_start = $start_date->diff(new DateTime($a));
    $minutes = $since_start->days * 24 * 60;
    $minutes += $since_start->h * 60;
    $minutes += $since_start->i;

    $time=

    $since_start->d.’ d,  ‘
    .$since_start->h.’ : ‘
    .$since_start->i.’ ‘;

    if($minutes > ’15’ and $minutes

    Ticket:

    Company:

    Ticket ID ()
    has been delivered to by

  12. Hello

    Excellent work and i know this is an old script but i have just come across it and it works great for what i need. But i do have a problem. On my webpage i have 2 input forms and because of this your scroll will not work. Can you help.

    Here is my code:

    Input1

    Input2

    Input3

    Could the problem be in the script.js file
    myFormSubmit = function () {
    	// set reference to the form
    	var frm = document.forms[0]; 
    	// set scroll position to the hidden form element
    	frm.scroll.value = my_scroll();
    	// submit form
    	frm.submit();
    };
    

    Thank you for your help

  13. I’m having the same issue with a form. I can get the page to resume scroll position by passing the scroll through GET, but the form button that I click does not submit the $POST data any longer, it is just an empty array. What am I doing wrong?

    Form method:

    My form button:
    echo “Save”;

Leave a Comment