[英]Using a ref to find and scroll to the top position of child element in React
I hope my approach to this is correct but I am trying to build a component in React where a bunch of posts are rendered in a column view stacked on top of one another, each individual post is set to 100vh.我希望我的方法是正确的,但我正在尝试在 React 中构建一个组件,其中一堆帖子呈现在一个堆叠在另一个顶部的列视图中,每个单独的帖子都设置为 100vh。
Psuedo Code伪代码
<container ref={postRef}>
<post 1/>
<post 2/>
<post 3/>
</container>
I have a ref
on the <container/>
and from another component's onClick
function I get the current index of the <post/>
I clicked on, and then find that element in the dom.我在
<container/>
上有一个ref
,从另一个组件的onClick
function 我得到了我点击的<post/>
的当前索引,然后在 dom 中找到该元素。
useEffect(() => {
if (postRef.current && indexOfClickedPost) {
const refBounds = postRef.current.children[indexOfClickedPost].getBoundingClientRect()
window.scrollTo({
top: // which unit goes here?
});
}
})
my end goal is to scroll my <container/>
component to the very top of the post relative to the one that was just clicked.我的最终目标是将我的
<container/>
组件滚动到帖子的最顶部,相对于刚刚单击的那个。
Ex.前任。 if the user clicks a post with an index of 2, the page will scroll to where the post 2 div begins
如果用户单击索引为 2 的帖子,页面将滚动到帖子 2 div 开始的位置
I am not sure which unit I am to put in my window.scrollTo
to get that effect.我不确定要在我的
window.scrollTo
中放入哪个单元才能达到这种效果。 Putting refBounds.top
does not yield the results I want, it seems to be doing nothing at all from what I can visibly see.放置
refBounds.top
不会产生我想要的结果,从我可以看到的情况来看,它似乎什么也没做。 Any advice would be great.任何建议都会很棒。 Thanks!
谢谢!
I propose two different approaches, the first one follows your trial, and it makes use of getBoundingClientRect()
to calculate the right distance from top and scrollTo
to scroll to that element:我提出了两种不同的方法,第一种方法遵循您的试验,它使用
getBoundingClientRect()
来计算与顶部的正确距离,并使用scrollTo
滚动到该元素:
function App() {
const [currPostIdx, setCurrPostIdx] = useState(0);
const containerRef = useRef();
const selectPost = (idx) => {
setCurrPostIdx(idx);
};
useEffect(() => {
const el = containerRef.current.children[currPostIdx];
const top = window.pageYOffset + el.getBoundingClientRect().top;
console.log(currPostIdx, top);
window.scrollTo(0, top);
}, [currPostIdx]);
return (
<>
<ul className="navbar">
{posts.map((p, i) => (
<li key={p.title} onClick={() => selectPost(i)}>
{p.title}
</li>
))}
</ul>
<div ref={containerRef}>
{posts.map((p, idx) => (
<Post key={p.title} post={p} idx={idx} />
))}
</div>
</>
);
}
const Post = ({ idx, post }) => (
<div
id={post.title}
className="post"
style={{ backgroundColor: `#${idx + 5}${idx * 3}${idx * 4}` }}
>
<h4>{post.title}</h4>
</div>
);
The seond approach makes use of hash navigation and hence it has not to calculate the position of the element manually:第二种方法使用 hash 导航,因此它不必手动计算元素的 position:
function App() {
return (
<div>
<div className="navbar">
{posts.map((p) => (
<a href={`#${p.title}`}>{p.title}</a>
))}
</div>
{posts.map((p, idx) => (
<Post key={p.title} post={p} idx={idx} />
))}
</div>
);
}
const Post = ({ idx, post }) => (
<div
id={post.title}
className="post"
style={{ backgroundColor: `#${idx + 5}${idx * 3}${idx * 4}` }}
>
<h4>{post.title}</h4>
</div>
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.