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

如何根据Div块内元素状态隐藏自定义滚动Prev/Next按钮

实现滚动容器的按钮显示/隐藏逻辑

要实现滚动到第一个元素时隐藏Prev按钮、滚动到最后一个元素时隐藏Next按钮、中间位置显示双按钮的效果,我们可以通过监听滚动容器的滚动事件,结合容器的滚动参数判断按钮显示状态,具体修改如下:

修改后的完整代码

import { useRef, useState, useEffect } from "react";

export default function App() {
  const cardsContainerRef = useRef();
  const [showPrevBtn, setShowPrevBtn] = useState(false);
  const [showNextBtn, setShowNextBtn] = useState(true);
  const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];

  const updateButtonVisibility = () => {
    const container = cardsContainerRef.current;
    if (!container) return;
    
    // 滚动到最左侧时隐藏Prev按钮(留5px容差避免浏览器精度问题)
    const isAtStart = container.scrollLeft <= 5;
    // 滚动到最右侧时隐藏Next按钮
    const isAtEnd = container.scrollLeft + container.clientWidth >= container.scrollWidth - 5;
    
    setShowPrevBtn(!isAtStart);
    setShowNextBtn(!isAtEnd);
  };

  const onPrevorNextBtnClick = (scrollOffset) => {
    cardsContainerRef.current.scrollLeft += scrollOffset;
    // 延迟更新状态,确保滚动动作完成后再判断位置
    setTimeout(updateButtonVisibility, 100);
  };

  useEffect(() => {
    const container = cardsContainerRef.current;
    if (!container) return;

    // 初始渲染时同步按钮状态
    updateButtonVisibility();
    // 添加滚动事件监听
    container.addEventListener("scroll", updateButtonVisibility);
    
    // 组件卸载时清理监听,避免内存泄漏
    return () => {
      container.removeEventListener("scroll", updateButtonVisibility);
    };
  }, []);

  return (
    <div>
      <div style={{ display: "flex", gap: "10px", alignItems: "center" }}>
        {showPrevBtn && (
          <button
            onClick={() => onPrevorNextBtnClick(-300)}
          >
            Prev
          </button>
        )}
        <div
          ref={cardsContainerRef}
          style={{ display: "flex", gap: "10px", overflow: "hidden", width: "500px" }}
        >
          {data.map((item, index) => (
            <div
              key={index}
              style={{
                width: "100px",
                height: "100px",
                flexShrink: 0,
                backgroundColor: "green",
                color: "white",
                display: "flex",
                alignItems: "center",
                justifyContent: "center"
              }}
            >
              {item}
            </div>
          ))}
        </div>
        {showNextBtn && (
          <button
            onClick={() => onPrevorNextBtnClick(300)}
          >
            Next
          </button>
        )}
      </div>
    </div>
  );
}

关键逻辑说明

  • 状态控制:通过showPrevBtn和showNextBtn两个状态变量,直接控制对应按钮的渲染与否
  • 滚动位置判断:
    • scrollLeft:容器已滚动的水平距离
    • clientWidth:容器的可见区域宽度
    • scrollWidth:容器内所有内容的总宽度
    • 增加5px容差是为了避免浏览器滚动精度误差导致的状态判断异常
  • 事件监听与清理:在组件挂载时添加滚动监听,初始渲染同步一次状态;卸载时移除监听,防止内存泄漏
  • 按钮点击后的状态更新:由于滚动是异步行为,通过setTimeout延迟执行状态判断,确保滚动动作完成后再更新按钮显示状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 10:15:33