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

点击ScrollToTop回到顶部按钮后如何设置焦点到其他组件的元素

实现方案

步骤1:改造ScrollToTop组件,支持滚动完成回调

首先修复原组件滚动事件重复绑定的问题,同时新增滚动完成后的回调触发逻辑,等待平滑滚动结束后执行自定义操作:

import { useState, useEffect, useCallback } from 'react';

interface ScrollToTopProps {
  onScrollComplete?: () => void;
}

const ScrollToTop = ({ onScrollComplete }: ScrollToTopProps) => {
  const [showScrollButton, setShowScrollButton] = useState<boolean>(false);

  const checkScrollToTop = useCallback(() => {
    setShowScrollButton(window.pageYOffset > 400);
  }, []);

  const scrollToTop = () => {
    window.scrollTo({ top: 0, behavior: 'smooth' });
    // 监听滚动结束事件,触发回调后自动解绑
    const handleScrollEnd = () => {
      onScrollComplete?.();
      window.removeEventListener('scrollend', handleScrollEnd);
    };
    window.addEventListener('scrollend', handleScrollEnd);
  };

  // 滚动事件绑定放到useEffect中,避免重复绑定、内存泄漏
  useEffect(() => {
    window.addEventListener('scroll', checkScrollToTop);
    return () => window.removeEventListener('scroll', checkScrollToTop);
  }, [checkScrollToTop]);

  if (!showScrollButton) return null;

  return (
    <button
      type='button'
      onClick={scrollToTop}
      aria-label="回到顶部"
    >
      回到顶部
    </button>
  );
}

export default ScrollToTop;

如果需要兼容不支持scrollend事件的旧浏览器,可以把滚动结束监听替换为定时触发,时长和滚动动画时长保持一致即可,示例:

setTimeout(() => onScrollComplete?.(), 500)

步骤2:改造List组件,暴露内部目标元素的ref

使用forwardRef将父组件传入的ref绑定到你需要聚焦的内部元素上,同时给非交互元素添加tabIndex=-1属性支持JS聚焦:

import { forwardRef } from 'react';

interface ListProps {
  collections: any[]; // 替换为你实际的collections类型
}

const List = forwardRef<HTMLDivElement, ListProps>(({ collections }, ref) => {
  return (
    <div className="list-container">
      {/* 将ref绑定到需要聚焦的目标元素,此处以列表标题为例,可替换为你实际的目标元素 */}
      <h2 ref={ref} tabIndex={-1}>列表标题</h2>
      {collections.map(item => (
        <div key={item.id} className="list-item">{item.content}</div>
      ))}
    </div>
  );
});

List.displayName = 'List';
export default List;

步骤3:父组件关联逻辑

在父组件中创建ref关联List内部的目标元素,给ScrollToTop传入滚动完成后聚焦目标元素的回调即可:

import { useRef } from 'react';
import List from './List';
import ScrollToTop from './ScrollToTop';

const YourPage = () => {
  const targetFocusRef = useRef<HTMLDivElement>(null);
  const collections = []; // 你的实际数据

  const handleScrollComplete = () => {
    targetFocusRef.current?.focus();
  };

  return (
    <>
      <div>
        <List collections={collections} ref={targetFocusRef} />
      </div>
      <ScrollToTop onScrollComplete={handleScrollComplete} />
    </>
  );
};

export default YourPage;

注意事项

  • 非交互元素(div、h1~h6等)必须添加tabIndex=-1属性才能通过JS调用focus方法生效,且该属性不会让元素被Tab键遍历选中,符合 accessibility 规范
  • 如果你的项目是JS版本,删除所有类型定义即可直接运行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:15:02