I have a header with a background color of transparent which will change to black when the user scrolls. Since I am using the requestAnimationFrame to accomplish this, the transition should pause when the tab is not active to save resources. I tested this with a function counting to 300 which indeed did pause when the tab was not active and resumed to 300 when active. However, it seems that my header's background color transition does not pause when on a new tab.
I am using mozilla's example which says "This example optimizes the scroll event for requestAnimationFrame." So I think it should work well with my use case (which it does) I would just like some insight as to why my transition doesn't pause when on a different tab to save resources and be as optimal as possible. Thanks! https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event
"use strict";
// Reference: http://www.html5rocks.com/en/tutorials/speed/animations/
const $ = selector => document.querySelector(selector);
let lastKnownScrollPosition = 0;
let ticking = false;
function doSomething(scrollPos) {
// Do something with the scroll position
if ( scrollPos > 0 ) {
$("header").style.backgroundColor = "black";
}
else {
$("header").style.backgroundColor = "transparent";
}
}
document.addEventListener('scroll', function(e) {
lastKnownScrollPosition = window.scrollY;
if (!ticking) {
window.requestAnimationFrame(function() {
doSomething(lastKnownScrollPosition);
ticking = false;
});
ticking = true;
}
});
Here is my JSFiddle https://jsfiddle.net/Boros/zjwyamvq/3/
A different approach would be to use an IntersectionObserver.
If you place a tiny (1px x 1px) element at the top of the page you can set an IntersectionObserver on it which will tell you as soon as it goes out of the viewport or comes back in.
That way you only have to run JS when there is a change from the user having scrolled away from the top - which will happen only once until they scroll back up to the top.
I don't know how much more efficient this is than using the traditional scroll and trying to throttle it, but MDN says:
sites no longer need to do anything on the main thread to watch for this kind of element intersection, and the browser is free to optimize the management of intersections as it sees fit.
The very fact that you aren't coming back to execute some JS every time the user does a scroll must help regardless of whether the browser does additional optimisation.
Here's a trivial example. It adds the 1px div, sets an IntersectionObserver on it and if the div goes out of the viewport that means the user has scrolled and if it is in the viewport the user has scrolled back to the top or the system is at the start position.
Note, if you want to make it slightly less sensitive you can set the check div to have a height of say 20px so if the user scrolls back to pretty near the top the color changes.
const $ = selector => document.querySelector(selector);
const check = (entries) => {
$("header").style.backgroundColor = (entries[0].isIntersecting) ? 'transparent' : 'black';
};
const observer = new IntersectionObserver(check);
observer.observe($("#checker"));
<div id="checker" style="width: 1px; height: 1pc; position: absolute; top: 0; left; 50%;"></div>
<header style="width: 100vw; height: 200vh; transition: 5s;">SCROLL DOWN TO SEE BACKGROUND COLOR CHANGE TO BLACK</header>