Reputation: 11777
Is it possibile to detect if an element has stopped scrolling in Mobile Safari via Javascript?
I have an element that has momentum scrolling by using -webkit-overflow-scrolling:touch
, and I need to detect if the element has stopped scrolling, including after the momentum affects the scroll.
Is this possible? Using the onscroll
event is not working as it should within my app.
Upvotes: 9
Views: 6132
Reputation: 281
You could also add a function that recursivly calls itself until the scrolling has stopped within the element and then call futher function from there.
isScrolling() {
var scrollStart = <element>.scrollTop;
setTimeout(function() {
var scrollPos = <element>.scrollTop;
if (scrollStart !== scrollPos) {
this.isScrolling()
} else {
// Scrolling has stopped
}
}, 100)
}
Upvotes: 0
Reputation: 1743
In my case this worked perfectly:
var timer;
$(scrollWrapper).on('scroll',function(e){
if(timer){
clearTimeout(timer);
}
timer = setTimeout(function(){
$(this).trigger('scrollFinished');
}, 55)
})
$(scrollWrapper).on('scrollFinished',function(){
// will be called when momentum scroll is finished
})
Publish 'scrollfinished' event when scroll has stopped.
Upvotes: 5
Reputation: 1155
You can calculate a swipe velocity and try to figure out if momentum scroll will occur based on some threshold value. I've done some testing and about 0.25 pixels/ms seems to be a good value.
Note: Sometimes momentum scrolling will occur for lower velocities too. The lowest velocity to cause momentum scrolling that I recorded was 0.13 (with very short delta time) so if you need a 100% perfect solution, keep on looking.
The example code also detects and deals with overscrolling.
Using JQuery;
var scrollWrapper = $('#myWrapper');
var starTime, startScroll, waitForScrollEvent;
scrollWrapper.bind('touchstart', function() {
waitForScrollEvent = false;
});
scrollWrapper.bind('touchmove', function() {
startTime = new Date().getTime(); startScroll = scrollWrapper.scrollTop();
});
scrollWrapper.bind('touchend', function() {
var deltaTime = new Date().getTime() - startTime;
var deltaScroll = Math.abs(startScroll - scrollWrapper.scrollTop());
if (deltaScroll/deltaTime>0.25
|| scrollWrapper.scrollTop()<0
|| scrollWrapper.scrollTop()>scrollWrapper.height()) {
// will cause momentum scroll, wait for 'scroll' event
waitForScrollEvent = true;
}
else {
onScrollCompleted(); // assume no momentum scroll was initiated
}
startTime = 0;
});
scrollWrapper.bind('scroll', function() {
if (waitForScrollEvent) {
onScrollCompleted();
}
});
Upvotes: 7