How to Know When I'Ve Stopped Scrolling

How do I check when the user has stopped scrolling?

In your component state, store the last time at which you've received a scroll event. In your render method, check when the last scroll event happened and decide whether your button should become visible again or not.

Rough example:

// Observe the scroll events.
<ScrollView onScroll={(e) => {
this.setState({lastScroll: new Date()})
}} />

// Check if the last scroll happened later than 300ms ago.
if (this.state.lastScroll.getTime() < (new Date()).getTime() - 300) {
// Render the button.
}

jQuery scroll() detect when user stops scrolling

$(window).scroll(function() {
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
// do something
console.log("Haven't scrolled in 250ms!");
}, 250));
});

Update

I wrote an extension to enhance jQuery's default on-event-handler. It attaches an event handler function for one or more events to the selected elements and calls the handler function if the event was not triggered for a given interval. This is useful if you want to fire a callback only after a delay, like the resize event, or such.

It is important to check the github-repo for updates!

https://github.com/yckart/jquery.unevent.js

;(function ($) {
var on = $.fn.on, timer;
$.fn.on = function () {
var args = Array.apply(null, arguments);
var last = args[args.length - 1];

if (isNaN(last) || (last === 1 && args.pop())) return on.apply(this, args);

var delay = args.pop();
var fn = args.pop();

args.push(function () {
var self = this, params = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(self, params);
}, delay);
});

return on.apply(this, args);
};
}(this.jQuery || this.Zepto));

Use it like any other on or bind-event handler, except that you can pass an extra parameter as a last:

$(window).on('scroll', function(e) {
console.log(e.type + '-event was 250ms not triggered');
}, 250);

http://yckart.github.com/jquery.unevent.js/

(this demo uses resize instead of scroll, but who cares?!)

Event when user stops scrolling

You can make the scroll() have a time-out that gets overwritten each times the user scrolls. That way, when he stops after a certain amount of milliseconds your script is run, but if he scrolls in the meantime the counter will start over again and the script will wait until he is done scrolling again.

Update:

Because this question got some action again I figured I might as well update it with a jQuery extension that adds a scrollEnd event

// extension:
$.fn.scrollEnd = function(callback, timeout) {
$(this).on('scroll', function(){
var $this = $(this);
if ($this.data('scrollTimeout')) {
clearTimeout($this.data('scrollTimeout'));
}
$this.data('scrollTimeout', setTimeout(callback,timeout));
});
};

// how to call it (with a 1000ms timeout):
$(window).scrollEnd(function(){
alert('stopped scrolling');
}, 1000);
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>

<div style="height: 200vh">
Long div
</div>

How do I know when I've stopped scrolling a TScrollBar?

Try this code (tested with Delphi 2009), it will fill the form client area with a random colour while you track the thumb, and fill it in yellow when the thumb is released:

procedure TForm1.ScrollBar1Scroll(Sender: TObject; ScrollCode: TScrollCode;
var ScrollPos: Integer);
begin
Randomize;
if ScrollCode = scTrack then
Color := RGB(Random(256), Random(256), Random(256));
if ScrollCode = scEndScroll then
Color := clYellow;
end;

The TScrollCode values map to the WPARAM values that you will find documented for WM_HSCROLL and WM_VSCROLL.

How can I detect window scroll ended in javascript?

You could use requestAnimationFrame to detect when the scrollTop is greater than y

requestAnimationFrame is way better than setting both an interval and an event listener on scroll, for a matter of performance.

const element = document.getElementById('element');
const y = element.getBoundingClientRect().top + window.scrollY;

function checkScrollEnd() {
if ((window.scrollY || document.body.scrollTop || document.documentElement.scrollTop) < y) {
window.requestAnimationFrame(checkScrollEnd);
}
else {
alert('end of scroll')
}
}

window.requestAnimationFrame(checkScrollEnd);

window.scroll({
top: y,
behavior: 'smooth'
});

Example fiddle

jQuery event listener when NOT scrolling in the browser?

Use a variable to track the status of the scrolling, and a timer to determine if the scrolling has been stopped for N seconds.

var scroll_active = false;
var scroll_timer = new Date();

Start your scroll timer:

check_scroll_time();

Then, on scroll, re-set the time-stamp in the scroll_timer variable:

$(window).scroll(function(){
scroll_timer = new Date();

//Your existing code goes here; No-scroll events are handled in check_scroll_time()
var scroll = jQuery(window).scrollTop();
if(scroll > position) { // scrolling down
// do something when scrolling down
} else if(scroll < position) { // scrolling up
// do something when scrolling up
}

});

Your scroll-monitoring function just needs to subtract the scroll_timer time from the current time and determine how long since the last scroll event:

function check_scroll_time(){
now = new Date();
if ((now.getTime() - scroll_timer.getTime())/1000 > 2){
//No scrolling - do something
}else{
//Scrolling is active - do nothing
}
setTimeout(function(){ check_scroll_time() },300); //<==== call ad-infinitum
}

Example:

var scroll_active = false;var scroll_timer = new Date();check_scroll_time();
$(window).scroll(function(){ scroll_timer = new Date();});
function check_scroll_time(){ now = new Date(); if ((now.getTime() - scroll_timer.getTime())/1000 > 2){ $('#msg').html('Paused'); }else{ $('#msg').html('Scrolling'); } setTimeout(function(){ check_scroll_time() },300);}
body{height:700vh;}#blurb{position:fixed;top:50px;width:100vw;text-align:center;}#msg{position:fixed;top:0;right:0;text-align:center;padding:5px;background:wheat;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script><div id="msg"></div><div id="blurb">Scroll away - watching for a 2-sec pause</div>

End of a scroll event in JS or vue

Ok so I know you don't really want to use a timer but it does seem like the appropriate way to do this since we don't really have a way to determine stopped scrolling. So how about something like this:

var scroll;
window.addEventListener('scroll', function (event) {
window.clearTimeout(scroll);
hidestuff();
scroll = setTimeout(function () {
redisplay();
}, 500);
}, false);

The above code refreshes the timer every time scroll is being triggered and if for half a second (500 milliseconds) no scroll is being performed a "stop scroll" is assumed and you call your logic to redisplay what you've hidden.

Event AFTER scroll event stops?

You could use a timer to check if you have scrolled in the last N ms and call a callback after that about of time.

var wrapper = document.getElementById('wrapper')
function onScroll(element, scrolling, stopped) { let timer = null // bind the event to the provided element element.addEventListener('scroll', function (e) { // use a class to switch the box-shadow on element.classList.add('scrolling') if (typeof scrolling === 'function') { scrolling.apply(this, arguments) } // clear the existing timer clearTimeout(timer) // set a timer for 100 ms timer = setTimeout(() => { // if we get in here the page has not been scrolled for 100ms // remove the scrolling class element.classList.remove('scrolling') if (typeof scrolling === 'function') { stopped.apply(this, arguments) } }, 100) })}
// call the functiononScroll(wrapper, function scrolling(e) { e.target.classList.add('scrolling') }, function stopped(e) { e.target.classList.remove('scrolling') })
* {  box-sizing: border-box;}
#wrapper { height: 200px; padding: 2em; overflow: auto; transition: .4s box-shadow;}
#wrapper.scrolling { box-shadow: 0px 0px 60px blue inset;}
#topBar > div { background: #eee; height: 200px; width: 200px; margin-bottom: 1em; position: relative; transition: .4s all;}
#wrapper.scrolling #topBar > div { transform: perspective(1200px) translateZ(20px); box-shadow: 2px 2px 10px #777;}
<div id="wrapper" class="">  <div class="" id="topBar">    <div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>  </div></div>


Related Topics



Leave a reply



Submit