簡體   English   中英

在 React 中使用 ref 查找並滾動到子元素的頂部 position

[英]Using a ref to find and scroll to the top position of child element in React

我希望我的方法是正確的,但我正在嘗試在 React 中構建一個組件,其中一堆帖子呈現在一個堆疊在另一個頂部的列視圖中,每個單獨的帖子都設置為 100vh。

偽代碼

<container ref={postRef}>
   <post 1/>
   <post 2/>
   <post 3/>
</container>

我在<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?
      });
    }
  })

我的最終目標是將我的<container/>組件滾動到帖子的最頂部,相對於剛剛單擊的那個。

前任。 如果用戶單擊索引為 2 的帖子,頁面將滾動到帖子 2 div 開始的位置

我不確定要在我的window.scrollTo中放入哪個單元才能達到這種效果。 放置refBounds.top不會產生我想要的結果,從我可以看到的情況來看,它似乎什么也沒做。 任何建議都會很棒。 謝謝!

我提出了兩種不同的方法,第一種方法遵循您的試驗,它使用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>
);

演示在這里

第二種方法使用 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM