Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How will you detect that a scroll caused by a swipe gesture has ended on a mobile web browser?

I have a horizontal slider for a web app which will be run in mobile browsers. I want to apply some styling right at the moment the scroll ends caused by a swipe gesture. This is the my html and css

.container {
  display: flex;
  overflow: scroll;
}

.box {
  flex-shrink: 0;
  width: 25%;
  height: 50px;
  background: yellow;
}

.box+.box {
  margin-left: 15px;
}
<body>
  <div class="container">
    <div class="box">
    </div>
    <div class="box">
    </div>
    <div class="box">
    </div>
    <div class="box">
    </div>
    <div class="box">
    </div>
    <div class="box">
    </div>
  </div>
</body>

Please note that I am not interested in finding when a user has fully scrolled the element, I am specifically interested in when a scroll ends caused by a swipe gesture. There is no scrollStart or scrollEnd event for browsers, there is only scroll event, but scroll event contains no such info allowing me to find that there are no scroll events afterwards.

like image 737
Muhammad Saqib Avatar asked Jan 29 '26 12:01

Muhammad Saqib


1 Answers

The question is quite old, but I couldn't find the answer, and I have just had to solve the problem myself, so I thought I can share this.

On a mobile device, after the swipe is done, and after touchEnd event, scrolling still takes some time. This makes it hard to manipulate scrollLeft and scrollTop properties in touchEnd callback.

I solved this with window.requestAnimationFrame (please note a polyfill is here: https://www.paulirish.com/2011/requestanimationframe-for-smart-animating/)

How it works:

  1. On touchEnd you start recording current scroll of the container - this is currentScroll variable.

  2. You call animation frame, and in the callback compare current scroll of the element (container.scrollLeft) with the recorded currentScroll. If they are the same, that means scrolling has ended. You can log it in the console or do anything else in here.

  3. If they are not the same, update currentScroll to reflect current scroll position and then call animation frame with the same callback, and it will check if container is still scrolling.

  4. Please note that in this case I used only scrollLeft property, since we are only swiping horizontally. The same can be used to test scrollTop.

var container = document.getElementById('container')

var detectScrollEnded = function(ev) {
  
  var currentScroll = container.scrollLeft
  
  function testIfScrolling() {
    if (container.scrollLeft !== currentScroll) {
      currentScroll = container.scrollLeft
      console.log('still scrolling...')
      window.requestAnimationFrame(testIfScrolling)
    } else {
      console.log('scrolling stopped!')
    }
  }
  
  window.requestAnimationFrame(testIfScrolling)
}

container.addEventListener('touchend', detectScrollEnded)
.container {
  display: flex;
  overflow: scroll;
}

.box {
  flex-shrink: 0;
  width: 25%;
  height: 50px;
  background: yellow;
}

.box+.box {
  margin-left: 15px;
}
<body>
  <div class="container" id="container">
    <div class="box">
    </div>
    <div class="box">
    </div>
    <div class="box">
    </div>
    <div class="box">
    </div>
    <div class="box">
    </div>
    <div class="box">
    </div>
  </div>
</body>
like image 117
Joanna Betlej Avatar answered Jan 31 '26 03:01

Joanna Betlej



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!