You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何在overflow:scroll的div内滚动到指定元素

解决React中自定义容器内部滚动到指定元素的问题

核心问题分析

你当前使用window.scrollTo()操作的是整个页面的滚动,而非目标.dayView容器的内部滚动。要实现容器内滚动,需要直接操作容器元素的滚动API,而非全局window对象。

具体解决方案

1. 使用React Ref获取容器元素

在组件中通过useRef绑定目标容器,这是更符合React最佳实践的DOM操作方式:

import { useRef, useEffect } from 'react';
import moment from 'moment';

const YourTimeBlockComponent = () => {
  // 创建ref绑定dayView容器
  const dayViewRef = useRef(null);

  const scrollToTime = () => {
    const currentHour = moment().hour().toString();
    // 获取当前时段的元素(注意:需保证每个timeSlot的id唯一)
    const currentTimeEl = document.getElementById(currentHour);
    const container = dayViewRef.current;

    if (container && currentTimeEl) {
      // 计算当前元素相对于容器内部的顶部偏移量
      const elementOffset = currentTimeEl.offsetTop - container.offsetTop;
      // 执行容器内部平滑滚动
      container.scrollTo({
        top: elementOffset,
        behavior: "smooth"
      });
    }
  };

  // 页面加载完成后触发滚动
  useEffect(() => {
    scrollToTime();
  }, []);

  return (
    <div className="dayView" ref={dayViewRef}>
      <hr className="day-divider1" />
      {/* 修正ID为唯一值,比如用24小时制命名 */}
      <div className='dayView-timeSlot' id="0">
        <Row className="time-row" >
          <Col md="1" className="time-label">12:00 AM</Col>
          <Col md="1" className="trash"><Trash /></Col>
          <Col md="8" className="appointment-slot">{" "}</Col>
        </Row>
      </div>
      <hr className="day-divider-dashed" />
      <div className='dayView-timeSlot' id="0-30">
        <Row className="time-row">
          <Col md="1" className="time-label">12:30 AM</Col>
          <Col md="1" className="trash"><Trash /></Col>
          <Col md="8" className="appointment-slot">{" "}</Col>
        </Row>
      </div>
      {/* 其他时段代码... */}
    </div>
  );
};

export default YourTimeBlockComponent;

2. 修正重复ID问题

你提供的代码中存在重复的id="12",这会导致document.getElementById只能获取到第一个匹配元素,无法定位到正确时段。建议将ID设置为唯一值:

  • 整点时段用24小时制数字命名(如12:00 AM对应id="0",1:00 AM对应id="1")
  • 半点时段可追加后缀区分(如12:30 AM对应id="0-30")
  • 如果需要匹配当前分钟对应的时段,可扩展逻辑:根据moment().minute()判断是否超过30,选择对应ID。

3. 优化容器样式

明确设置垂直滚动,避免不必要的水平滚动干扰:

.dayView{
  height: 75vh;
  overflow-y: scroll; /* 仅开启垂直滚动 */
}

偏移量计算补充方案

如果offsetTop计算结果不准确,可改用getBoundingClientRect()获取视口位置进行精确计算:

const scrollToTime = () => {
  const currentHour = moment().hour().toString();
  const currentTimeEl = document.getElementById(currentHour);
  const container = dayViewRef.current;

  if (container && currentTimeEl) {
    const containerRect = container.getBoundingClientRect();
    const elementRect = currentTimeEl.getBoundingClientRect();
    // 计算元素相对于容器内部的滚动距离
    const scrollTop = elementRect.top - containerRect.top + container.scrollTop;
    
    container.scrollTo({
      top: scrollTop,
      behavior: "smooth"
    });
  }
};

内容的提问来源于stack exchange,提问作者CourtneyJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:06:02