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

如何实现高度与页面Y轴滚动坐标关联的动态自定义滚动条

实现方案

核心逻辑

  • 计算页面最大可滚动距离:document.documentElement.scrollHeight - window.innerHeight,即页面总高度减去视口高度,为用户可滚动的总范围
  • 监听全局滚动事件,用当前滚动距离除以最大可滚动距离得到滚动进度百分比
  • 将进度百分比作为props传递给styled组件,动态控制内层滚动条的高度

1. 调整样式组件代码

修改DynamicScrollbar的高度取值,从组件props中获取动态进度:

import styled from 'styled-components';

export const DynamicScrollbarContainer = styled.div`
    position: fixed;
    right: 5%;
    top: 35%;
    width: 2px;
    height: 300px;
    background-color: rgba(255,255,255,0.5);
   
    @media ${(props) => props.theme.breakpoints.xl} {
        display: none;
    }
`;

export const DynamicScrollbar = styled.div`
    width: 100%;
    height: ${props => props.scrollProgress || 0}%;
    background-color: #ffffff;
    transition: height 0.1s ease; // 可选,添加过渡让高度变化更流畅
`

2. 调整组件逻辑代码

添加滚动事件监听、进度计算逻辑,注意组件卸载时清理事件监听避免内存泄漏:

import React, { useState, useEffect } from 'react';
import { DynamicScrollbarContainer, DynamicScrollbar } from './ScrollbarStyles';

const ScrollBar = () => {
  const [scrollProgress, setScrollProgress] = useState(0);
  // 节流定时器标识
  let scrollTimer = null;

  const handleScroll = () => {
    // 200ms节流,减少触发频率
    if (scrollTimer) return;
    scrollTimer = setTimeout(() => {
      // 计算总可滚动高度
      const totalScrollableHeight = document.documentElement.scrollHeight - window.innerHeight;
      // 页面内容不足一屏时特殊处理
      if (totalScrollableHeight <= 0) {
        setScrollProgress(100);
        scrollTimer = null;
        return;
      }
      // 计算进度百分比
      const progress = (window.scrollY / totalScrollableHeight) * 100;
      setScrollProgress(progress);
      scrollTimer = null;
    }, 200);
  };

  useEffect(() => {
    // 组件挂载时添加监听,同时触发一次计算初始进度
    window.addEventListener('scroll', handleScroll);
    handleScroll();
    // 组件卸载时移除监听
    return () => {
      window.removeEventListener('scroll', handleScroll);
      if (scrollTimer) clearTimeout(scrollTimer);
    };
  }, []);

  return (
    <DynamicScrollbarContainer>
      <DynamicScrollbar scrollProgress={scrollProgress} />
    </DynamicScrollbarContainer>
  );
};

export default ScrollBar;

可选适配说明

如果是监听局部容器的滚动而非页面全局滚动,只需要做以下调整:

  • 将监听对象从window替换为对应滚动容器的DOM节点
  • 滚动距离取值从window.scrollY替换为容器的scrollTop属性
  • 总高度取值从document.documentElement.scrollHeight替换为容器的scrollHeight属性
  • 视口高度取值从window.innerHeight替换为容器的clientHeight属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 01:24:01