Next.js 14:Framer Motion useScroll元素容器无法更新滚动进度问题
问题原因及解决方法
核心问题
- 滚动容器绑定错误:
useScroll的container参数需指向实际发生滚动的元素(即带有overflow-x-scroll的motion.main),而非内部的内容容器div。之前将carouselRef绑定在内容容器上,导致Framer Motion无法正确检测滚动行为。 - 未监听滚动进度变化:声明了
useMotionValueEvent但未实际使用,无法将scrollXProgress的实时值同步到progress状态中。 - 拼写错误:
setPorgress应为setProgress,状态更新函数名称错误导致无法更新值。
修改后的代码
'use client' import { useRef, useState } from 'react'; import { useScroll, useTransform, motion, useMotionValueEvent } from "framer-motion"; export default function Home() { // 将ref绑定到实际滚动容器 const carouselRef = useRef(null); // 修复拼写错误 const [progress, setProgress] = useState(0); const { scrollXProgress } = useScroll({ container: carouselRef, // 可选:明确滚动进度计算边界,提升精准度 offset: ["start start", "end end"] }); // 监听滚动进度变化,同步更新状态 useMotionValueEvent(scrollXProgress, "change", (latest) => { setProgress(latest.toFixed(2)); }); const background = useTransform(scrollXProgress, [0, 1], ['rgb(255, 255, 255)', 'rgb(220, 0, 0)']); return ( // 将ref绑定到这个具备滚动属性的容器上 <motion.main ref={carouselRef} className='h-full flex items-center overflow-x-scroll snap-x snap-mandatory' style={{ background }} > <div className='flex gap-4'> <div className='bg-red-500 h-96 rounded-md w-[calc(100vw_-_2rem)] mx-4 p-4 text-white snap-center shadow-lg'> <h1>Card</h1> { progress } </div> <div className='bg-blue-500 h-96 rounded-md w-[calc(100vw_-_2rem)] mx-4 p-4 text-white snap-center shadow-lg'> <h1>Card</h1> </div> <div className='bg-green-500 h-96 rounded-md w-[calc(100vw_-_2rem)] mx-4 p-4 text-white snap-center shadow-lg'> <h1>Card</h1> </div> </div> </motion.main> ); }
关键修改说明
- 滚动容器绑定:将
carouselRef移至motion.main,因为它是带有overflow-x-scroll的滚动容器,Framer Motion需要监听该元素的滚动事件。 - 进度同步逻辑:通过
useMotionValueEvent监听scrollXProgress的change事件,将实时滚动进度同步到progress状态,toFixed(2)用于简化小数显示。 - offset配置:
useScroll的offset参数明确了进度计算的边界——从内容顶部与视口顶部对齐,到内容底部与视口底部对齐时,进度从0过渡到1,确保进度计算精准。
内容的提问来源于stack exchange,提问作者Baraa Halabi
相关产品推荐
相关产品推荐

