---
title: "useElementByPoint 用法与示例"
description: "`useElementByPoint` 是一个用于获取指定坐标下的元素的 Hook。"
canonical: https://reactuse.com/zh-Hans/browser/useelementbypoint/
---

# useElementByPoint

`useElementByPoint` 是一个用于获取指定坐标下的元素的 Hook。

`useElementByPoint` 封装了 [`document.elementFromPoint()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/elementFromPoint)（在多元素模式下使用 `elementsFromPoint()`），用于响应式地查询给定 x/y 坐标处的 DOM 元素。它支持通过定时器或 `requestAnimationFrame` 进行轮询，并返回一个可暂停的对象，包含匹配的元素、`isSupported` 标志和 `pause`/`resume` 控件。

### 使用场景

- 构建元素检查工具或可视化调试器，高亮显示悬停的元素
- 实现自定义拖放逻辑，需要检测特定坐标处的放置目标
- 创建交互式教程或入门覆盖层，识别光标下的 UI 元素

### 注意事项

- **SSR 安全**：在服务端渲染期间返回 `isSupported: false` 和 `null` 元素。服务端不会访问 `document`。
- **性能**：使用 `interval` 选项控制轮询频率。`requestAnimationFrame` 提供最流畅的更新，但 CPU 使用较高。
- **相关 hooks**：可配合 `useMouse` 跟踪光标位置，以及 `useElementBounding` 获取检测到元素的尺寸。

## Usage

```tsx live noInline  
function Demo() {
  const { clientX: x, clientY: y } = useMouse();
  const { element, pause, resume } = useElementByPoint({ x, y });
  const bounding = useElementBounding(element);

  useEventListener("scroll", bounding.update, null, { capture: true });
  const boxStyles = (() => {
    if (element) {
      return {
        display: "block",
        width: `${bounding.width}px`,
        height: `${bounding.height}px`,
        left: `${bounding.left}px`,
        top: `${bounding.top}px`,
        backgroundColor: "#3eaf7c44",
        transition: "all 0.05s linear",
        position: "fixed",
        pointerEvents: "none",
        zIndex: 9999,
        border: "1px solid var(--vp-c-brand)",
      };
    }
    return {
      display: "none",
    };
  })();
  const pointStyles = (() => ({
    transform: `translate(calc(${x}px - 50%), calc(${y}px - 50%))`,
    position: "fixed",
    top: 0,
    left: 0,
    pointerEvents: "none",
    width: "8px",
    height: "8px",
    borderRadius: "50%",
    backgroundColor: "#4ade80",
    boxShadow: "0 0 2px rgba(0,0,0,0.3)",
    zIndex: 999,
  }))();

  return (
    <>
      <div style={boxStyles} />
      <div style={pointStyles} />
      <div style={{ display: "flex", alignItems: "center" }}>
        <span style={{ marginRight: "16px" }}>X: {x}</span>
      </div>
      <div style={{ display: "flex", alignItems: "center" }}>
        <span style={{ marginRight: "16px" }}>Y: {y}</span>
      </div>
      <div>
        <button onClick={pause}>暂停</button>
        <button onClick={resume}>恢复</button>
      </div>
    </>
  );
}
render(<Demo />);
```

%%API%%