Home > Software engineering >  Store Animation State When Coming Back To URL
Store Animation State When Coming Back To URL

Time:08-28

I have a simple JS scroll event that when an element gets to within 50px of the top of the window the header animates and changes colour, which is done by using getBoundingClientRect().top < 50 on a trigger element. This functionality is only on the home page of the site.

Is there anyway of having it so when a user visits another URL/page on the site, and then comes back to this page via the browsers back arrow, that the previous animation state is still applied? If the page reloads and starts at the top again it doesn't matter, but if you click back to the page that uses this code, the menu transition happens even if you return to part of the page that was past the trigger point. I don't want to force the page to the top each time because this page is going to have downloadable and searchable info on, so that it would be real pain to be sent back to the top of that page each time.

I've given a working example below and via the CodePen link, the problem is of course on CodePen and StackOverflow when you go to a different URL and then click back to URL in question it actually reloads the page from scratch again, which doesn't happen as standard browser behaviour on day-to-day websites.

Codepen: https://codepen.io/anna_paul/pen/bGvPWRj

In that back end I'm using PHP, and I do have access to this is there needs to be a server side solution.

Any ideas or suggestions appreciated.

Note: On the actual site this scroll event is invoked via a debounce function, but I have removed this for code simplicity.

let triggerElement = document.getElementById('trigger-element'),
header = document.getElementById('h')

let menuChange = function() {
 if(triggerElement.getBoundingClientRect().top < 50) {
      header.style.background = 'black'
      header.style.transition = '1s'
  } else {
      header.style.background = 'red'
      header.style.transition = '.15s'
  }
}

window.addEventListener('scroll', menuChange)
body {
  margin: 0;
  height: 200vh;
}

#h {
  display: flex;
  justify-content: center;
  background: red;
  color: #fff;
  position: fixed;
  top: 0;
  width: 100%;
}

#trigger-element {
  margin-top: 150px;
  padding: 1rem;
  background:blue;
  color: #fff;
}
<header id="h">
  <p>HEADER CONTENT</p>
</header>
<div id="trigger-element">Trigger Element</div>

CodePudding user response:

I recommend using localStorage for this particular use case, because it can easily be implemented alongside your current method:

const triggerElement = document.getElementById('trigger-element');
const header = document.getElementById('h');

const animationTriggered = localStorage.getItem('animationTriggered') === 'true';
let initialLoad = true;

const menuChange = function() {
  if (animationTriggered && initialLoad) {
    header.style.background = 'black';
  } else if (triggerElement.getBoundingClientRect().top < 50) {
    header.style.background = 'black';
    header.style.transition = '1s';
    localStorage.setItem('animationTriggered', 'true');
  } else {
    header.style.background = 'red';
    header.style.transition = '.15s';
    localStorage.setItem('animationTriggered', 'false');
  }
  
  initialLoad = false;
}

window.addEventListener('scroll', menuChange);

This will remember the previous state and apply the black background color if the animation was previously triggered. This adds a small amount of overhead, but in a real-world scenario it should not have any noticeable impact on the performance of the application.

  • Related