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

React中如何设置组件默认滚动位置且不滚动整个页面

解决日历组件独立滚动不影响父页面的问题

你的核心问题是日历容器未被设置为独立滚动容器,导致调用滚动操作时实际触发了父页面的滚动;同时浏览器的滚动冒泡机制会优先滚动父元素到边界后再处理子元素。以下是具体解决方法:

1. 将日历容器设为独立滚动上下文

给日历容器添加overflow-y: auto(或overflow-y: scroll)样式,让它拥有自己的滚动区域,内部滚动不会影响父页面:

<div
  ref={calendarRef}
  style={{
    scrollMarginTop: '1000px',
    height: '700px',
    position: 'relative', 
    marginLeft: '40px',
    overflowY: 'auto', // 关键:开启垂直滚动
    overflowX: 'hidden', // 可选:隐藏水平滚动条
  }}
>

2. 优化滚动触发逻辑

确保DOM完全渲染后再执行滚动操作,避免容器未就绪导致的异常;同时通过聚焦容器阻止滚动冒泡到父页面:

useEffect(() => {
  const scrollCalendar = () => {
    if (calendarRef.current) {
      calendarRef.current.focus(); // 聚焦容器,隔离父页面滚动
      calendarRef.current.scrollTo({
        top: 500,
        behavior: 'auto' // 禁用动画,避免滚动链触发父页面
      });
    }
  };
  // 等待DOM渲染完成
  requestAnimationFrame(scrollCalendar);
}, []);

3. 额外适配:让容器可聚焦

给日历容器添加tabIndex="-1"属性,使其成为可聚焦元素,确保focus()方法生效:

<div
  ref={calendarRef}
  tabIndex="-1"
  style={{/* ...其他样式 */}}
>

修改后的完整组件代码

export default function WeeklyCalendar({classes, clinicals, blockedTime, fileClinicalList}) {
  const calendarRef = useRef(null);

  useEffect(() => {
    const scrollCalendar = () => {
      if (calendarRef.current) {
        calendarRef.current.focus();
        calendarRef.current.scrollTo({
          top: 500,
          behavior: 'auto'
        });
      }
    };
    requestAnimationFrame(scrollCalendar);
  }, []);


  return (
    <div>
        <div
          style={{
            position: 'sticky',
            zIndex: '10',
            backgroundColor: PlatformStyles.LogoNavyBlue,
            width: '100%',
            top: '0px',
            left: '-10%',
            right: '50px',
            fontWeight: 'bold'
          }}
          >
          {days.map((day , index) => {
            let width = columnWidth
            if (index === 0) {
              width = '5%'
            }
            return (
              <div
              style={{
                position: '',
                display: 'inline-block',
                zIndex: 11,
                color: 'white',
                width,
                textAlign: 'center'
              }}
              >
              {day}    
            </div>
            )
            
          })}
        </div>
    <div
      ref={calendarRef}
      tabIndex="-1"
      style={{
        scrollMarginTop: '1000px',
        height: '700px',
        position: 'relative', 
        marginLeft: '40px',
        overflowY: 'auto',
        overflowX: 'hidden'
      }}
      >
        {hours.map((hour) => {

          let id = hour
          if (hour === 6) {
            id = 'scrollId'
          }

          return (
            <div
            key={hour}
            id={id}
            style={{
              position: 'absolute',
              top: `${(hour - 0.5) * multiplier + .51}%`,
              bottom: `${100 - (hour + 1) * multiplier}%`,
              left: '-2%',
              right: '0%',
              fontSize: '11px',
              textAlign: 'left',
              fontWeight: 'bold',
              alignItems: 'center'
            }}
          >
            {convertTime(hour)}
          </div>
          )
          
        })}
        
        {/* Adds line in the middle of the hour */}
        {hours.map((hour) => 
          <div
            key={hour}
            style={{
              position: 'absolute',
              top: `${hour * multiplier}%`,
              bottom: `${100 - (hour + 1) * multiplier}%`,
              left: '.5%',
              right: '0%',
              marginLeft: '22px',
              borderBottom: '1px solid lightgray',
              textAlign: 'left',
              fontWeight: 'bold',
              alignItems: 'center'
            }}
          >
          </div>
        )}
        {events.map((event, index) => 
          event.day.map((day) => 
          <Event
            key={`event-${index}-${day}`}
            event={event}
            day={day}
            />
          )
        )}
    </div>
    </div>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 14:45:34