0

I am looking for a JS solution that will

  1. return true while the user is scrolling and
  2. false as soon as the user stops scrolling

I have looked at this similar question, but rather than checking if the user is scrolling it will just set a variable after scrolling and you have to manually manage the state before and after.

userHasScrolled = false; 
window.onscroll = function (e) { userHasScrolled = true; }

I'd rather see a function that checks on call if the user is currently scrolling. Something like below. But I can't figure out how to do that with the onscroll event, or if it's possible at all.

items.forEach(item => {
  item.addEventListener('mouseenter', () => showItem());
});

function userIsScrolling() {
  // check if user is currently scrolling
  if () {
    return true
  } else {
    return false
  }
}

function showItem() {
  if (!userIsScrolling()) {
    // if user is not scrolling, execute function logic
  }
}

PS: Might make more sense to check userIsScrolling before adding the eventListener. But then we also need to think about logic to remove the eventListener. Open for suggestions on this.

SaroGFX
  • 699
  • 6
  • 20
  • 1
    `window.addEventListener('scroll', () => /* set a variable to true and a setTimeout to set that variabele to false after x ms */)` and then access that variable – eroironico Dec 14 '22 at 12:44
  • 2
    https://dirask.com/posts/JavaScript-scroll-stop-event-pVyxGD – grisuu Dec 14 '22 at 12:45
  • @grisuu exactly what i was talking about – eroironico Dec 14 '22 at 12:46
  • @Nick True, but I just used that example ;-) – grisuu Dec 14 '22 at 12:52
  • 1
    @Nick, I have tried that, but what it was missing is the clearTimeout for it to work properly. – SaroGFX Dec 14 '22 at 12:57
  • Unfortunately there is a problem. Inside the onmouseover event it will be set as 'done scrolling', but not updated. How can I make it so that the return value from createScrollStopListener also updates the variable inside the mouseover event? – SaroGFX Dec 14 '22 at 13:57

1 Answers1

0

After a comment with a link to a working snippet, I have added an example that is working. Posting it here as an answer too for future reference.

let userIsScrolling;

function createScrollStopListener(element, callback, timeout) {
  var handle = null;
  var onScroll = function() {
    if (handle) {
      clearTimeout(handle);
    }
    handle = setTimeout(callback, timeout || 400)
    userIsScrolling = true;
  };
  element.addEventListener('scroll', onScroll);
  return function() {
    element.removeEventListener('scroll', onScroll);
  };
}

createScrollStopListener(window, function() {
  userIsScrolling = false;
});


const listItems = document.querySelectorAll('li')

listItems.forEach((item) => {
  item.addEventListener('mouseenter', () => {
    if (userIsScrolling === false) {
      console.log('mouse over item when not scrolling')
    } else {
      console.log('mouse over when user is scrolling')
    }
  })
})
body {
  height: 200vh;
}

ul li {
  width: 300px;
  height: 100px;
  margin: 1em;
  background: tomato;
}
Scroll page to see console


<ul>
  <li>Mouse over me while scrolling</li>
  <li>Mouse over me while scrolling</li>
  <li>Mouse over me while scrolling</li>
  <li>Mouse over me while scrolling</li>
  <li>Mouse over me while scrolling</li>
  <li>Mouse over me while scrolling (or not)</li>
</ul>
SaroGFX
  • 699
  • 6
  • 20