Remove hover effects when scrolling

Tags: , , , ,



I have been working on an application. There are multiple components on the page. The content inside them is scrollable. The expected functionality is when I scroll inside the component the hover effects on different elements should be disabled. After searching in the internet I have a working solution. I have created a HoverDisabler component like this,

import React, {useEffect} from 'react';

export const HoverDisabler = ({children}) => {
  let timer = 0;
  useEffect(() => { 
     document.addEventListener('scroll', () => {
        clearTimeout(timer);
        if(!document.body.classList.contains('hoverDisabled')){
            document.body.classList.add('hoverDisabled');
        }
        timer = setTimeout(() => {
            document.body.classList.remove('hoverDisabled');
        },500);
     }, true); 
  }, []);
  return children;
}

The css for hoverDisabled is as follows,

.hoverDisabled {
    pointer-events: 'none',
}

And I am wrapping my root App component with HoverDisabler like this,

<HoverDisabler><App /></HoverDisabler>

Now in all the component, if I start scrolling the hoverDisabled class is added in the body and it gets removed when I stop scrolling. Everything is working perfectly. I am curious if this is the correct approach of having this functionality? Is there any shortcomings of this approach or some problem I am overlooking because of my lack of experience?

Answer

Since scroll event is an expensive event you can add a debounce on your scroll event like this:

function debounce(method, delay) {
    clearTimeout(method._tId);
    method._tId= setTimeout(function(){
        method();
    }, delay);
}
function scrollFunction(){
   clearTimeout(timer);
    if(!document.body.classList.contains('hoverDisabled')){
        document.body.classList.add('hoverDisabled');
    }
    timer = setTimeout(() => {
        document.body.classList.remove('hoverDisabled');
    },500);
}
document.addEventListener('scroll', function() {
    debounce(scrollFunction, 100);
});

This will surely optimize your code, as it will only fire scroll function lesser number of times. Even though there may be other approaches to the problem you’re trying to solve I’m just suggesting a way to optimize your current code.



Source: stackoverflow