useScroll
This is an example of a Reactive Component that can get the scroll position of the element and whether or not the starting point (or ending point) has been reached.
Try scrolling horizontally on the next screen.
scrollPos
when the scroll changes, isReachStart
when the scroll reaches the start point, and isReachEnd
when the scroll reaches the end point.
* pos: 0
* start: not reached
* end: not reached
* start: not reached
* end: not reached
Reactive Adapter
const REACTIVE_ADAPTER = ({ onInit, onDestroy, getProps }) => {
const obj = reactive({
isReachStart: false,
isReachEnd: false,
});
const ref = getProps().ref;
const onScroll = () => {
const element = ref.value || ref.current;
const scrollLeft = element.scrollLeft;
obj.isReachStart = scrollLeft === 0;
obj.isReachEnd = scrollLeft === element.scrollWidth - element.clientWidth;
};
onInit(() => {
const element = ref.value || ref.current;
element?.addEventListener("scroll", onScroll);
onScroll();
});
onDestroy(() => {
const element = ref.value || ref.current;
element?.removeEventListener("scroll", onScroll);
});
return obj;
};
Frameworks
- React
- Vue@2
- Vue@3
- Svelte
You can create a Reactive Component by importing the @cfcs/react
module and using the useReactive
function.
import React from "react";
import { useReactive } from "@cfcs/react";
function useScroll() {
const ref = React.useRef(null);
return Object.assign(useReactive(ADAPTER, () => ({ ref })), {
ref,
});
}
export function App() {
const { scrollPos, isReachStart, isReachEnd, ref } = useScroll();
return <div>
* pos: {scrollPos} <br />
* start: {isReachStart ? "reached": "not reached"} <br />
* end: {isReachEnd ? "reached" : "not reached"}
<div className="scroll-container" ref={ref}>...</div>
</div>;
}