Reputation: 3117
I use reactjs and want to handle scroll with click
event.
Firstly, I rendered list of posts with componentDidMount
.
Secondly, by click event
on each post in list, It will display post detail and scroll to top (because I put post detail to top position of page).
Thirdly, by clicking "close button"
in post detail, it will return previous list of posts but I want website will scroll to exactly to position of clicked post.
I use like this:
Click event to view post detail:
inSingle = (post, e) => {
this.setState({
post: post,
theposition: //How to get it here?
});
window.scrollTo(0, 0);
}
I want to get state of theposition
then I can do scroll exactly to position of clicked post by 'Close event'
.
Upvotes: 75
Views: 263068
Reputation: 1704
This should work:
this.setState({
post: post,
theposition: window.pageYOffset
});
EDIT: To update the vertical position every time you scroll, you could utilize event listeners
like this (also suggested by Lucas Andrade in a separate answer):
const [scrollYPosition, setScrollYPosition] = React.useState(0);
const handleScroll = () => {
const newScrollYPosition = window.pageYOffset;
setScrollYPosition(newScrollYPosition);
};
React.useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []);
// Now the vertical position is available with `scrollYPosition`
console.log(scrollYPosition)
And here's a bit of trivia:
window.pageYOffset
is an alias of window.scrollY
property which returns the number of pixels that the document is currently scrolled
vertically from the origin, i.e. Y coordinate of the top edge of the current viewport. If the document is not scrolled at all up or down, then scrollY
is 0.
Similarly, you can get the number of pixels the document is scrolled horizontally from the origin using scrollX
property (window.pageXOffset
alias).
Reference: https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollY
Upvotes: 35
Reputation: 1
Also you can use a npm package to track the user scroll position https://www.npmjs.com/package/react-hook-collections
Upvotes: 0
Reputation: 241
Use window.scrollY instead of window.pageYOffset(deprecated).
const [scrollPosition, setScrollPosition] = useState(0);
useEffect(() => {
if (typeof window !== "undefined") {
const handleScroll = () => {
const position = window.scrollY;
setScrollPosition(position);
}
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}
}, [])
Upvotes: 0
Reputation: 1280
Combining some of the other answers, this is exactly what is needed here. Simply use this hook to get the scrollX (horizontal) and scrollY (vertical) positions from the window. It'll be updated as the user scrolls.
/// in useWindowScrollPositions.js
import { useEffect, useState } from 'react'
export const useWindowScrollPositions = () => {
const [scrollPosition, setPosition] = useState({ scrollX: 0, scrollY: 0 })
useEffect(() => {
function updatePosition() {
setPosition({ scrollX: window.scrollX, scrollY: window.scrollY })
}
window.addEventListener('scroll', updatePosition)
updatePosition()
return () => window.removeEventListener('scroll', updatePosition)
}, [])
return scrollPosition
}
Then call the hook in your function component:
/// in MyComponent.jsx
import { useWindowScrollPositions } from 'path/to/useWindowScrollPositions'
export const MyComponent = () => {
const { scrollX, scrollY } = useWindowScrollPositions()
return <div>Scroll position is ({scrollX}, {scrollY})</div>
}
Note that
window.pageXOffset
andwindow.pageYOffset
, which were used in the other answers from years ago, have been deprecated in favor ofwindow.scrollX
andwindow.scrollY
Upvotes: 10
Reputation: 1348
Found this on MDN:
element.scrollHeight - Math.abs(element.scrollTop) === element.clientHeight
Upvotes: 1
Reputation: 1059
You can use the native react event listener.
<div onScroll={(e) => console.log("scrolling!", e.target.scrollTop)}>
<h3>Some huge div</h3>
</div>
Upvotes: 8
Reputation: 4570
In case you need to keep on track of the scroll position, you can use react hooks to do so, that way it's possible to check the scroll position any time you need it:
import React, { useState, useEffect } from 'react';
...
// inside component:
const [scrollPosition, setScrollPosition] = useState(0);
const handleScroll = () => {
const position = window.pageYOffset;
setScrollPosition(position);
};
useEffect(() => {
window.addEventListener('scroll', handleScroll, { passive: true });
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []);
In this case useEffect
will behavior similar to componentDidMount
, it will fire once the component has rendered, but also in every render, as Jared Beach commented bellow: "window.addEventListener is smart enough to discard subsequent calls with the same parameters". . Make sure to return the cleanup function, similar to what you'd do in componentWillUnmount
.
Upvotes: 87
Reputation: 181
import React, { useLayoutEffect, useState } from 'react';
export default function useWindowPosition() {
const [scrollPosition, setPosition] = useState(0);
useLayoutEffect(() => {
function updatePosition() {
setPosition(window.pageYOffset);
}
window.addEventListener('scroll', updatePosition);
updatePosition();
return () => window.removeEventListener('scroll', updatePosition);
}, []);
return scrollPosition;
}
Upvotes: 18
Reputation: 1095
this repo helped me a lot https://github.com/n8tb1t/use-scroll-position
yarn add @n8tb1t/use-scroll-position
import { useScrollPosition } from '@n8tb1t/use-scroll-position'
useScrollPosition(({ prevPos, currPos }) => {
console.log(currPos.x)
console.log(currPos.y)
})
Upvotes: 1
Reputation: 5929
You can use event listener in react like you will use in other js framework or library.
componentDidMount() {
window.addEventListener('scroll', this.listenToScroll)
}
componentWillUnmount() {
window.removeEventListener('scroll', this.listenToScroll)
}
listenToScroll = () => {
const winScroll =
document.body.scrollTop || document.documentElement.scrollTop
const height =
document.documentElement.scrollHeight -
document.documentElement.clientHeight
const scrolled = winScroll / height
this.setState({
theposition: scrolled,
})
}
Upvotes: 57
Reputation: 85545
Like this:
theposition: e.y // or, e.pageY
Or,
theposition: e.clientY - e.currentTarget.getBoundingClientRect().top
Upvotes: 4
Reputation: 55
to get current scroll position you can use
horizontal scrolling amount window.pageXOffset
vertical scrolling amount window.pageYOffset
Upvotes: 3