---
title: "useScroll 用法與示例"
description: "跟蹤滾動位置和統計數據。"
canonical: https://reactuse.com/zh-Hant/browser/usescroll/
---

# useScroll

跟蹤滾動位置和統計數據

`useScroll` 追蹤可捲動元素的捲動位置、方向和邊緣到達狀態。它回傳一個物件，包含 `x` 和 `y` 位置、`isScrolling` 狀態、每個方向的 `arrivedState`（是否到達邊緣）和 `directions`（捲動方向）。支援節流和偏移量設定。

### 使用場景

- 建構捲動進度指示器或基於捲動的動畫
- 偵測使用者何時捲動到頂部或底部以顯示/隱藏元素
- 實作根據捲動位置觸發的視差效果

### 注意事項

- **SSR 安全**：在伺服器端渲染時位置回傳 `0`，`isScrolling` 回傳 `false`，到達和方向狀態為預設值。伺服器上不會附加捲動監聽器。
- **節流**：使用 `throttle` 選項限制捲動處理器的觸發頻率，以提升複雜捲動式 UI 更新的效能。
- **相關 hooks**：另請參閱 `useInfiniteScroll` 用於自動載入更多觸發，`useScrollLock` 用於停用捲動，以及 `useScrollIntoView` 用於程式化捲動。

## Usage

```tsx live

function Demo() {
  const elementRef = useRef<HTMLDivElement>(null);
  const [x, y, isScrolling, arrivedState, directions] = useScroll(elementRef);
  const { left, right, top, bottom } = useMemo(
    () => arrivedState,
    [arrivedState],
  );
  const {
    left: toLeft,
    right: toRight,
    top: toTop,
    bottom: toBottom,
  } = useMemo(() => directions, [directions]);

  const absoluteStyle: CSSProperties = {
    paddingTop: "0.25rem",
    paddingBottom: "0.25rem",
    paddingLeft: "0.5rem",
    paddingRight: "0.5rem",
    position: "absolute",
  };
  return (
    <div style={{ display: "flex" }}>
      <div
        ref={elementRef}
        style={{
          width: 300,
          height: 300,
          margin: "auto",
          borderRadius: "0.25rem",
          overflow: "scroll",
        }}
      >
        <div style={{ width: 500, height: 400, position: "relative" }}>
          <div
            style={{
              ...absoluteStyle,
              top: "0rem",
              left: "0rem",
            }}
          >
            左上
          </div>
          <div
            style={{
              ...absoluteStyle,
              bottom: "0rem",
              left: "0rem",
            }}
          >
            左下
          </div>
          <div
            style={{
              ...absoluteStyle,
              top: "0rem",
              right: "0rem",
            }}
          >
            右上
          </div>
          <div
            style={{
              ...absoluteStyle,
              bottom: "0rem",
              right: "0rem",
            }}
          >
            右下
          </div>
          <div
            style={{
              ...absoluteStyle,
              top: "33.33333%",
              left: "33.33333%",
            }}
          >
            滾動我
          </div>
        </div>
      </div>
      <div
        style={{
          width: 280,
          margin: "auto",
          paddingLeft: "1rem",
          display: "flex",
          flexDirection: "column",
          gap: 5,
        }}
      >
        <div>
          位置：{x.toFixed(1)}, {y.toFixed(1)}
        </div>
        <div>正在滾動：{JSON.stringify(isScrolling)}</div>
        <div>到達頂部：{JSON.stringify(top)}</div>
        <div>到達右側：{JSON.stringify(right)}</div>
        <div>到達底部：{JSON.stringify(bottom)}</div>
        <div>到達左側：{JSON.stringify(left)}</div>
        <div>向上滾動：{JSON.stringify(toTop)}</div>
        <div>向右滾動：{JSON.stringify(toRight)}</div>
        <div>向下滾動：{JSON.stringify(toBottom)}</div>
        <div>向左滾動：{JSON.stringify(toLeft)}</div>
      </div>
    </div>
  );
};

```

%%API%%