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

点击按钮后容器无法滚动?React横向滑块问题求助

问题:横向滑块点击圆点按钮无法触发滚动

我正在实现一个带按钮的横向滑块,包含6个卡片和6个点按钮。点击索引为1的第二个按钮时,应该滑动到第二张图片,但滚动事件完全没生效。

相关代码

CSS代码

@media only screen and (max-width: 810px){
    .fake-magicwall ul{
        overflow: hidden;
        overflow-x: auto;
        flex-wrap: nowrap;

    }

    .dot{
        width: 15px;
        height: 15px;
        border-radius: 50%;
        margin: 10px;
      
    }
}

React组件代码

import React from 'react'
import './Work.css'
import Cta from '../atoms/Cta'
import Headphone from '../assets/images/headphones3.png'
import Calendar from '../assets/images/calendar.png'
import DevConnector from '../assets/images/dev.png'
import Bulls from '../assets/images/bulls2.png'
import Expenses from '../assets/images/reactExpenses.png'
import SixFlags from '../assets/images/sixflags.png'
import useDots from '../hooks/useDots';


const images = [Calendar, Headphone, SixFlags, DevConnector, Bulls, Expenses];

const Work = () => {
    const [activeIndex, setActiveIndex] = useDots(images.length);

    function handleDotClick(index) {
        console.log("Clicked dot with index:", index);
      
        setActiveIndex(index);
      
        const targetCard = document.querySelector(`[data-id="${index}"]`);
        console.log("Target card:", targetCard);
      
        if (targetCard) {
          const magicWall = document.getElementById('home-magicwall');
          console.log("Magic wall:", magicWall);
          console.log("Target card offsetLeft:", targetCard.offsetLeft);
          console.log("Magic wall offsetLeft:", magicWall.offsetLeft);
      
          magicWall.scroll({
            left: targetCard.offsetLeft - magicWall.offsetLeft,
            behavior: 'smooth'
          });
        }
      }
      
      
      
    return (
      <div className="main-container">
        <section id="section-work">
          <div id="header">
            <h2>My Work</h2>
          </div>
          <div className="text-zone-2">
            <div>
              <p>
                A small gallery of recent projects chosen by me. I've done them all together with amazing people from
                companies around the globe. It's only a drop in the ocean compared to the entire list. Interested to see
                some more? Visit my work page.
                <br />
              </p>
            </div>
            <div className="btn-container">
              <Cta className="btn" link="https://github.com/mateoghidini1998" content="See More" />
            </div>
          </div>
          <div className="fake-big-2">Work</div>
        </section>
        <div className="dots">
            {images.map((image, index) => (
              <button
                key={index}
                className={`dot ${index === activeIndex ? 'active' : ''}`}
                onClick={() => handleDotClick(index)}
              ></button>
            ))}
          </div>
        <div id="home-magicwall" className="fake-magicwall">
          <ul>
            {images.map((image, index) => (
              <li key={index} className={`magic-wall_item ${index === activeIndex ? 'active' : ''}`}>
                <img src={image} alt="image" />
                <div className="hover-content"></div>
                <a href="/" className="colorbox" data-id={index}></a>
              </li>
            ))}
          </ul>
  
          
        </div>
      </div>
    );
  };
  
export default Work;

自定义Hook代码

import { useState } from 'react';

function useDots(images) {
  const [activeIndex, setActiveIndex] = useState(0);

  return [activeIndex, setActiveIndex];
}

export default useDots;

排查情况

已通过console.log确认:

  • 点击的点按钮索引正确
  • <a>标签的data-id属性值正确
  • 每次点击能输出Target card offsetLeft: 133和Magic wall offsetLeft: 0
    但滚动操作完全不生效。

原因分析

核心问题是滚动容器找错了:
你的CSS明确设置了.fake-magicwall ul的overflow-x: auto,也就是真正具备横向滚动能力的是<ul>元素;但当前代码中调用scroll()方法的是它的父元素#home-magicwall,这个父元素没有开启滚动属性,所以执行滚动操作不会有任何效果。

另外,你当前获取的目标元素是<a>标签,而它是<li>的子元素,基于子元素的offsetLeft计算滚动位置可能会有偏差,应该直接以<li>(卡片容器)作为目标参考。


解决方案

1. 修正滚动容器和目标元素

修改handleDotClick函数,将滚动容器改为<ul>,目标元素改为对应的<li>:

function handleDotClick(index) {
    console.log("Clicked dot with index:", index);
  
    setActiveIndex(index);
  
    // 改为获取对应的li元素(给li加上data-id属性)
    const targetLi = document.querySelector(`.magic-wall_item[data-id="${index}"]`);
    console.log("Target li:", targetLi);
  
    if (targetLi) {
      // 获取真正的滚动容器:ul元素
      const scrollContainer = document.querySelector('#home-magicwall ul');
      console.log("Scroll container:", scrollContainer);
      
      // 直接基于li的offsetLeft设置滚动位置
      scrollContainer.scroll({
        left: targetLi.offsetLeft,
        behavior: 'smooth'
      });
    }
}

2. 给<li>添加data-id属性

在渲染<li>时加上data-id={index},方便准确获取目标元素:

<li key={index} data-id={index} className={`magic-wall_item ${index === activeIndex ? 'active' : ''}`}>
  <img src={image} alt="image" />
  <div className="hover-content"></div>
  <a href="/" className="colorbox"></a>
</li>

3. 确保横向布局的完整性(可选)

如果<ul>和<li>的横向布局还存在问题,可以补充以下CSS:

.fake-magicwall ul {
  display: flex; /* 启用flex布局 */
  gap: 10px; /* 卡片间间距,可根据需求调整 */
}

.fake-magicwall li {
  flex-shrink: 0; /* 禁止卡片收缩,保证宽度一致 */
  width: 200px; /* 设置卡片固定宽度,可根据需求调整 */
}

额外优化:使用React Ref替代DOM查询(推荐)

在React中直接操作DOM不是最佳实践,建议用useRef来获取滚动容器:

import React, { useRef } from 'react'

const Work = () => {
    const [activeIndex, setActiveIndex] = useDots(images.length);
    const scrollRef = useRef(null); // 创建ref
    
    function handleDotClick(index) {
        setActiveIndex(index);
        const targetLi = scrollRef.current.children[index]; // 通过ref直接获取子元素
        if (targetLi && scrollRef.current) {
            scrollRef.current.scroll({
                left: targetLi.offsetLeft,
                behavior: 'smooth'
            });
        }
    }
    
    return (
        // ...其他代码
        <div id="home-magicwall" className="fake-magicwall">
          <ul ref={scrollRef}> {/* 绑定ref到ul */}
            {/* ...li元素 */}
          </ul>
        </div>
        // ...其他代码
    )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 05:42:26