EN
React - scroll stop event
4 points
In this short article, we would like to show how to detect scroll stop event ('scroll end event').
The solution for the problem is to use some trick: do some logic when scroll event doesn't occur few milliseconds after appeared.
Note: to make element scrollable we should use one of the
overflow
style property (e.g.overflowY: 'scroll'
).
Runnable example:
xxxxxxxxxx
1
// Note: uncomment import lines in your project.
2
// import React from 'react';
3
// import ReactDOM from 'react-dom';
4
5
const createScrollStopListener = (element, callback, timeout) => {
6
let removed = false;
7
let handle = null;
8
const onScroll = () => {
9
if (handle) {
10
clearTimeout(handle);
11
}
12
handle = setTimeout(callback, timeout || 200); // default 200 ms
13
};
14
element.addEventListener('scroll', onScroll);
15
return () => {
16
if (removed) {
17
return;
18
}
19
removed = true;
20
if (handle) {
21
clearTimeout(handle);
22
}
23
element.removeEventListener('scroll', onScroll);
24
};
25
};
26
27
const useScrollStopListener = (callback, timeout) => {
28
const containerRef = React.useRef();
29
const callbackRef = React.useRef();
30
callbackRef.current = callback;
31
React.useEffect(() => {
32
const destroyListener = createScrollStopListener(containerRef.current, () => {
33
if (callbackRef.current) {
34
callbackRef.current();
35
}
36
});
37
return () => destroyListener();
38
}, [containerRef.current]);
39
return containerRef;
40
};
41
42
43
// Usage example
44
45
const App = () => {
46
const containerRef = useScrollStopListener(() => {
47
console.log('onscrollstop');
48
});
49
return (
50
<div ref={containerRef} style={{ height: '200px', overflowY: 'scroll' }}>
51
<div style={{ height: '700px', background: 'silver' }}>
52
Scroll me up, down, up down and stop!
53
</div>
54
</div>
55
);
56
};
57
58
const root = document.querySelector('#root');
59
ReactDOM.render(<App />, root);
We are able to indicate window
as scrolled element
.
xxxxxxxxxx
1
// Note: uncomment import lines in your project.
2
// import React from 'react';
3
// import ReactDOM from 'react-dom';
4
5
const createScrollStopListener = (element, callback, timeout) => {
6
let removed = false;
7
let handle = null;
8
const onScroll = () => {
9
if (handle) {
10
clearTimeout(handle);
11
}
12
handle = setTimeout(callback, timeout || 200); // default 200 ms
13
};
14
element.addEventListener('scroll', onScroll);
15
return () => {
16
if (removed) {
17
return;
18
}
19
removed = true;
20
if (handle) {
21
clearTimeout(handle);
22
}
23
element.removeEventListener('scroll', onScroll);
24
};
25
};
26
27
const useScrollStopListener = (element, callback, timeout) => {
28
const callbackRef = React.useRef();
29
callbackRef.current = callback;
30
React.useEffect(() => {
31
const destroyListener = createScrollStopListener(element, () => {
32
if (callbackRef.current) {
33
callbackRef.current();
34
}
35
});
36
return () => destroyListener();
37
}, [element]);
38
};
39
40
41
// Usage example
42
43
const App = () => {
44
useScrollStopListener(window, () => {
45
console.log('onscrollstop');
46
});
47
return (
48
<div style={{ height: '1000px', background: 'silver' }}>
49
Scroll me up, down, up down and stop!
50
</div>
51
);
52
};
53
54
const root = document.querySelector('#root');
55
ReactDOM.render(<App />, root);