Check when user is scrolling
Answered
Savannah posted this in #help-forum
SavannahOP
Hey guys, i'm trying to check when user is scrolling down or up to change my header's behavior, but
My Header.tsx component :
I've the console.log('hello world'), but never the console.log('scrolling')
window.addEventListener("scroll") is never listened toMy Header.tsx component :
const [isActive, setIsActive] = useState<boolean>(false);
const [prevScrollPos, setPrevScrollPos] = useState<number>(0);
const [isVisible, setIsVisible] = useState<boolean>(true);
function toggleMenu() {
setIsActive(!isActive);
}
useEffect(() => {
console.log('hello world')
const handleScroll = () => {
console.log('scrolling')
const currentScrollPos = window.scrollY;
const headerDiv = document.querySelector("header");
if (prevScrollPos < currentScrollPos && currentScrollPos > 100) {
setIsVisible(false);
} else {
setIsVisible(true);
}
setPrevScrollPos(currentScrollPos);
};
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, [prevScrollPos]);I've the console.log('hello world'), but never the console.log('scrolling')
Answered by Savannah
html, body {
overflow-x: hidden;
/*
min-height: 100svh;
*/
min-height: 100lvh;
background: $white;
}56 Replies
American Crow
I'd use a battle tested hook e.g. from mantine:
https://mantine.dev/hooks/use-in-viewport/
its open source if you want to check out the source code yourself or do any changes
https://mantine.dev/hooks/use-in-viewport/
its open source if you want to check out the source code yourself or do any changes
@Savannah Hey guys, i'm trying to check when user is scrolling down or up to change my header's behavior, but `window.addEventListener("scroll")` is never listened to
My Header.tsx component :
tsx
const [isActive, setIsActive] = useState<boolean>(false);
const [prevScrollPos, setPrevScrollPos] = useState<number>(0);
const [isVisible, setIsVisible] = useState<boolean>(true);
function toggleMenu() {
setIsActive(!isActive);
}
useEffect(() => {
console.log('hello world')
const handleScroll = () => {
console.log('scrolling')
const currentScrollPos = window.scrollY;
const headerDiv = document.querySelector("header");
if (prevScrollPos < currentScrollPos && currentScrollPos > 100) {
setIsVisible(false);
} else {
setIsVisible(true);
}
setPrevScrollPos(currentScrollPos);
};
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, [prevScrollPos]);
I've the console.log('hello world'), but never the console.log('scrolling')
you can't and shouldn't update prevSCrollPos within the hook, it will lead to the infinite loop, you don't need to pass prevScrollPos in the useEffect if using listener. try removing the prevlScrollPos from the effect args:
useEffect(() => {
console.log('hello world')
const handleScroll = () => {
console.log('scrolling')
const currentScrollPos = window.scrollY;
const headerDiv = document.querySelector("header");
if (prevScrollPos < currentScrollPos && currentScrollPos > 100) {
setIsVisible(false);
} else {
setIsVisible(true);
}
setPrevScrollPos(currentScrollPos);
};
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);@American Crow I'd use a battle tested hook e.g. from mantine:
https://mantine.dev/hooks/use-in-viewport/
its open source if you want to check out the source code yourself or do any changes
SavannahOP
Hey, thanks for your answer. But that's not what i'm looking for unfortunately. I try to check when user is scrolling down or up to display or hide my header
@American Crow I'd use a battle tested hook e.g. from mantine:
https://mantine.dev/hooks/use-in-viewport/
its open source if you want to check out the source code yourself or do any changes
SavannahOP
i tried with the useWindowEvent hook but not working too
@Savannah hey, i tried but it's not working, the event is never listened to
bring listener outside the hook and repass the prevscrollpos
@Coffee Coke bring listener outside the hook and repass the prevscrollpos
SavannahOP
outside the useEffect ?
yes
SavannahOP
nothing change
or maybe try passing window in the hook if that won't work
@Coffee Coke or maybe try passing window in the hook if that won't work
SavannahOP
not working too
The prob is that the event is never listen to
idk why
import type {GetServerSideProps, Metadata} from "next";
import { Inter } from "next/font/google";
import Header from "@/app/components/Header";
import {getServerSession, Session} from "next-auth";
import SessionProvider from "@/app/lib/auth/SessionProvider";
import Footer from "@/app/components/Footer";
import "@/styles/pages/layout.scss";
import "@/styles/general.scss";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "",
description: "Generated by create next app",
keywords: [
/* "Next.js",
"TypeScript",
"Tailwind CSS",*/
]
};
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const session = await getServerSession();
return (
<html lang="fr">
<body className={inter.className}>
<SessionProvider session={session}>
<div className="container-pages">
<Header/>
{children}
<Footer/>
</div>
</SessionProvider>
</body>
</html>
);
}`This is my layout.tsx
maybe it's because i'm scrolling inside the children and the header is declared above ?
SavannahOP
bump
@Savannah Hey guys, i'm trying to check when user is scrolling down or up to change my header's behavior, but `window.addEventListener("scroll")` is never listened to
My Header.tsx component :
tsx
const [isActive, setIsActive] = useState<boolean>(false);
const [prevScrollPos, setPrevScrollPos] = useState<number>(0);
const [isVisible, setIsVisible] = useState<boolean>(true);
function toggleMenu() {
setIsActive(!isActive);
}
useEffect(() => {
console.log('hello world')
const handleScroll = () => {
console.log('scrolling')
const currentScrollPos = window.scrollY;
const headerDiv = document.querySelector("header");
if (prevScrollPos < currentScrollPos && currentScrollPos > 100) {
setIsVisible(false);
} else {
setIsVisible(true);
}
setPrevScrollPos(currentScrollPos);
};
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, [prevScrollPos]);
I've the console.log('hello world'), but never the console.log('scrolling')
I only read this message, and here is what I did to detect:
let scrollY = 0;
function handleScroll() {
if (window.scrollY < 100) { if (transparentOnTop) { setColor('transparent') } return setScrolling(true); }
if (transparentOnTop) { setColor(bgColor) }
if (window.scrollY < scrollY) {
setScrolling(true);
} else {
setScrolling(false);
}
scrollY = window.scrollY
};Northern Inuit Dog
Try moving the header to the client and see if that works. Yeah I didn’t think server comps you can attach handlers. Console log in the listener.
@Savannah and FYI, react setState are just queues, so they don't update immediately
@Anay-208 I only read this message, and here is what I did to detect:
js
let scrollY = 0;
function handleScroll() {
if (window.scrollY < 100) { if (transparentOnTop) { setColor('transparent') } return setScrolling(true); }
if (transparentOnTop) { setColor(bgColor) }
if (window.scrollY < scrollY) {
setScrolling(true);
} else {
setScrolling(false);
}
scrollY = window.scrollY
};
SavannahOP
how did you trigger the handleScroll function ?
useEffect(() => {
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
//eslint-disable-next-line
}, []);@Northern Inuit Dog Try moving the header to the client and see if that works. Yeah I didn’t think server comps you can attach handlers. Console log in the listener.
SavannahOP
My header component is already a client component
@Anay-208 js
useEffect(() => {
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
//eslint-disable-next-line
}, []);
SavannahOP
but when i did that, the event is never listened to xD
umm are you sure, maybe try console logging
@Anay-208 umm are you sure, maybe try console logging
SavannahOP
i'll do that when i'm home 😉
alright
SavannahOP
But i'm pretty sure nothing was loged
@Anay-208 whenever you reach your home
SavannahOP
Yes, I'm in class actually, I finish at 7:30 p.m 😉
SavannahOP
@Anay-208 i try this :
function handleScroll() {
console.log('scroll');
}
useEffect(() => {
console.log('useEffect');
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);`The console.log('scroll') is triggered only when my scrollbar is at the end of my page
but not when scrolling down or up
@Savannah <@755810867878297610> i try this :
tsx
function handleScroll() {
console.log('scroll');
}
useEffect(() => {
console.log('useEffect');
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);`
Try removing the return statement
@Anay-208 Try removing the return statement
SavannahOP
nothing change ^^
Can you give a min repro repo?
@Anay-208 Can you give a min repro repo?
SavannahOP
i've to create one, i send it to you when he's done
it's working on it...
But it lacks the logic of next-js with the trump etc.
So idk what am i doing wrong tbh
Like the event is only trigger when my scrollbar is at the end 😢
@Savannah But it lacks the logic of next-js with the trump etc.
Create a min repro repo with nextjs
@Anay-208 Create a min repro repo with nextjs
SavannahOP
i did it and it's working wtf
Umm
@Anay-208 I only read this message, and here is what I did to detect:
js
let scrollY = 0;
function handleScroll() {
if (window.scrollY < 100) { if (transparentOnTop) { setColor('transparent') } return setScrolling(true); }
if (transparentOnTop) { setColor(bgColor) }
if (window.scrollY < scrollY) {
setScrolling(true);
} else {
setScrolling(false);
}
scrollY = window.scrollY
};
Maybe you should mark this message as a solution
@Anay-208 Maybe you should mark this message as a solution
SavannahOP
yeah but why it's not working on main project lmao
cause on the repo i just created, i just put the layout and the header/footer components
hum i found where is the problem @Anay-208
Drop it here and mark it as solution
SavannahOP
html, body {
overflow-x: hidden;
/*
min-height: 100svh;
*/
min-height: 100lvh;
background: $white;
}Answer
SavannahOP
The problem is the
overflow-x: hidden@Anay-208 Mark this as solution
SavannahOP
Thanks for your help bro