Skip to content

Keep scroll position and save toggle after page refresh

A long content sub-page has multiple “read more” buttons done with jquery toggleClass.

When a user click the “read more” button the content is showing and the page gets refreshed. (I need the page-refresh for various reasons).

When the page gets refreshed, of course the content is not unfold anymore.

What I am trying todo is:

  • Save all unfold / fold toggle content before the page-refresh.
  • Go to the same scroll position before the page-refresh.

I am not sure what is the best way to keep the information -> Cookies, sessionStorage or localStorage for my case, because the user will usually open more sub-pages with “read more” buttons.

I made a JSFiddle (page refresh is not working on a fiddle).

Answer

I’d advise using sessionStorage for this.

First, remove all onclick=refreshPage() from your HTML. You want to keep all JS code inside your JS, and to set all handlers at one place. As a best practice, do not use onclick at all.

Next, create two functions: loadState() and saveState(). You will need to call call loadState() on every page load (refresh), and saveState() everytime a toggle button is clicked.

In your handler for clicks on button, also perform the page refresh.

The entire JS code:

$(window).on('load', function() {
  loadState();
});

$('.read-more-toggle').on('click', function() {
  $(this).next('.read-more-content').toggleClass('hide');

  saveState();
  refreshPage();
});

// Fold or unfold each content based on state before refresh
// And go to same scroll position before refresh
function loadState() {
  let hidden_states = sessionStorage.getItem('hidden-states');
  if (!hidden_states) {
    return;
  }
  hidden_states = hidden_states.split(',');
  $('.read-more-content').each(function(i, elem) {
    if (hidden_states[i] === 'hide') {
      elem.classList.add('hide');
    }
    else {
      elem.classList.remove('hide');
    }
  });

  document.scrollingElement.scrollLeft = sessionStorage.getItem('scroll-x');
  document.scrollingElement.scrollTop = sessionStorage.getItem('scroll-y');
}

// Remember fold & unfold states, and scroll positions
function saveState() {
  let hidden_states = [];
  $('.read-more-content').each(function(i, elem) {
    hidden_states.push(elem.classList.contains('hide') ? 'hide' : 'show');
  });

  sessionStorage.setItem('hidden-states', hidden_states);
  sessionStorage.setItem('scroll-x', document.scrollingElement.scrollLeft);
  sessionStorage.setItem('scroll-y', document.scrollingElement.scrollTop);
}

function refreshPage() {
  window.location.reload();
}

Note: If at all possible, try to avoid a page refresh. Storing view states then recreating them after a refresh feels sub-optimal. In some browsers, it may also result in occasional scroll jump glitches as it repaints the restored states.

Lastly, consider if you really need jQuery for your project. Most functionality can be implemented in vanilla JS.