You need to enable JavaScript to run this app. React电商产品行向右滚动进度条开发:解决addEventListener为null报错
优惠活动
大模型
产品
解决方案
定价
更多

React电商产品行向右滚动进度条开发:解决addEventListener为null报错

报错原因&修复方案

你现在遇到的报错本质是选择器写错导致拿不到对应DOM元素,加上多处混用DOM和组件实例方法,不符合React开发规范,以下是完整修复步骤和代码:

具体错误点

  • 你用document.querySelector("CDG")选择元素,querySelector里类名需要加.前缀,正确写法是.CDG,没加前缀就会返回null,调用addEventListener自然就报错了
  • 不要直接用原生API操作DOM,React推荐用ref获取DOM引用,避免渲染时序导致的拿不到元素问题
  • 你把DOM元素当成了组件实例,调用element.calculateScrollDistance()和element.setState()都是错的,setState是组件的方法,不是DOM的方法
  • 组件卸载时没有移除滚动监听,会有内存泄漏风险

修复后完整代码

import React from 'react';
import { taskData } from "./cdg-data";
import ProgressBar from './progress';

class CDG extends React.Component {
  state = {
    scrollPosition: 0
  }
  // 声明ref存储滚动容器的DOM引用
  scrollRef = React.createRef();

  calculateScrollDistance = () => {
    const element = this.scrollRef.current;
    if (!element) return;
    const pixels = element.scrollLeft; // 当前滚动的像素值
    const elementWidth = element.clientWidth; // 容器可见宽度
    const fullElementWidth = element.scrollWidth; // 容器总宽度(含滚动隐藏部分)
    const totalScrollableDistance = fullElementWidth - elementWidth;
    // 处理滚动到底部时分母为0的边界情况
    const scrollPosition = totalScrollableDistance === 0 ? 0 : Math.floor(pixels / totalScrollableDistance * 100);
    this.setState({
      scrollPosition,
    })
  }

  listenToScrollEvent = () => {
    const element = this.scrollRef.current;
    if (!element) return;
    element.addEventListener("scroll", this.handleScroll);
  }

  handleScroll = () => {
    requestAnimationFrame(this.calculateScrollDistance);
  }

  componentDidMount() {
    this.listenToScrollEvent();
  }

  componentWillUnmount() {
    // 组件卸载时移除监听,避免内存泄漏
    const element = this.scrollRef.current;
    if (element) {
      element.removeEventListener("scroll", this.handleScroll);
    }
  }

  render() {
    return(
      <div>
        <h2 className="cdg-title">THE COLLECTION</h2>
        {/* 把ref绑定到滚动容器上 */}
        <div className="CDG" ref={this.scrollRef}>
          {taskData.map((item, index) => {
            // 给遍历的元素加key属性,避免React警告
            return (
              <div className="image-container" key={index}>
                <a href={item.url} target="_blank" rel="noreferrer">
                  <p className="title">{item.title}</p>
                  <p className="price">{item.price}</p>
                </a>
                <img className="cdg-image" 
                  src={item.image} 
                  alt="Converse"
                />
              </div>
            );
          })}
        </div>
        <div className="Progress">
          <ProgressBar scroll={this.state.scrollPosition + '%'}/>
        </div>
      </div>
    );
  }
}

export default CDG;

额外说明

如果你的.CDG容器还没加滚动样式,记得补上css才能触发滚动事件:

.CDG {
  display: flex;
  overflow-x: auto;
  /* 其他你需要的宽高、间距样式 */
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 20:48:03