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

Next.js中jQuery代码运行异常 子div轮播添加active类失效

Next.js 无限轮播active类切换异常修复方案

核心问题原因

  • 原有jQuery逻辑直接操作DOM,和Next.js的SSR hydration、React虚拟DOM机制冲突:代码执行时DOM可能未完成挂载,后续React重渲染也会覆盖jQuery对DOM的改动
  • 定时器未在组件卸载时清除,导致多定时器重复执行,轮播逻辑混乱
  • 初始状态未给第一个子元素添加active类,首次执行时选择器找不到目标元素,逻辑报错
  • 部分img标签缺失data-info属性,读取描述时返回undefined

可选修复方案

方案1:兼容原有jQuery逻辑(临时修复用,不推荐长期使用)

把DOM操作逻辑放到useEffect钩子中执行,确保DOM挂载完成后再初始化轮播,同时添加初始类名、卸载时清除定时器,代码示例:

import { useEffect, useState } from 'react';
import $ from 'jquery';
// 引入对应CSS Module为st,引入ae、pr、ps、xd图片资源

export default function SoftwareCarousel() {
  const [value, setValue] = useState({
    name: 'After effects',
    description: 'this is aftereffects'
  })

  useEffect(() => {
    const $container = $(".softwares_container");
    // 初始化给第一个子元素加active类
    $container.children().eq(0).addClass(st.active);

    const timerList = [];
    $container.each(function () {
      const $currentSet = $(this);
      const timer = setInterval(function () {
        const $cur = $currentSet.find(`.${st.active}`).removeClass(`${st.active}`);
        const $next = $cur.next().length ? $cur.next() : $currentSet.children().eq(0);
        $next.addClass(`${st.active}`);
        const $nextInner = $next.children().eq(0);
        setValue({
          name: $nextInner.attr('alt'),
          description: $nextInner.attr('data-info') || ''
        })
      }, 1000);
      timerList.push(timer)
    })

    // 组件卸载时清除所有定时器,避免内存泄漏和逻辑冲突
    return () => {
      timerList.forEach(timer => clearInterval(timer))
    }
  }, [])

  return (
    <div>
      <div className={`softwares_container ${st.left_container}`}>
        <div className={` ${st.img}`} alt="1">
          <img src={ae.src} data-info="this is aftereffects" alt="After effects" />
        </div>
        <div className={st.img} alt="2">
          <img src={pr.src} alt="Adobe Premiere pro" data-info="this is adobe premiere pro" />
        </div>
        <div className={st.img}>
          <img src={ps.src} alt="Adobe Photoshop" data-info="this is adobe photoshop" />
        </div>
        <div className={st.img}>
          <img src={xd.src} alt="Adobe Xd" data-info="this is adobe xd" />
        </div>
      </div>
      {/* 信息展示区域 */}
      <div className={st.content}>
        <h3>{value.name}</h3>
        <p>{value.description}</p>
      </div>
    </div>
  )
}

方案2:React状态驱动实现(推荐,符合Next.js开发规范)

完全移除jQuery依赖,用组件状态控制轮播逻辑和类名切换,从根源避免虚拟DOM和原生DOM操作的冲突,代码更易维护:

import { useEffect, useState } from 'react';
// 引入对应CSS Module为st,引入ae、pr、ps、xd图片资源

// 统一维护轮播数据
const softwareItems = [
  {
    name: 'After effects',
    description: 'this is aftereffects',
    imgSrc: ae.src
  },
  {
    name: 'Adobe Premiere pro',
    description: 'this is adobe premiere pro',
    imgSrc: pr.src
  },
  {
    name: 'Adobe Photoshop',
    description: 'this is adobe photoshop',
    imgSrc: ps.src
  },
  {
    name: 'Adobe Xd',
    description: 'this is adobe xd',
    imgSrc: xd.src
  }
]

export default function SoftwareCarousel() {
  const [activeIndex, setActiveIndex] = useState(0);

  useEffect(() => {
    const timer = setInterval(() => {
      // 循环更新索引,到最后一项时回到第一个
      setActiveIndex(prev => prev === softwareItems.length - 1 ? 0 : prev + 1)
    }, 1000)
    // 组件卸载清除定时器
    return () => clearInterval(timer)
  }, [])

  const currentActive = softwareItems[activeIndex]

  return (
    <div>
      <div className={`softwares_container ${st.left_container}`}>
        {softwareItems.map((item, index) => (
          <div
            key={item.name}
            // 索引匹配时添加active类
            className={`${st.img} ${index === activeIndex ? st.active : ''}`}
            alt={index + 1}
          >
            <img src={item.imgSrc} data-info={item.description} alt={item.name} />
          </div>
        ))}
      </div>
      {/* 信息展示区域 */}
      <div className={st.content}>
        <h3>{currentActive.name}</h3>
        <p>{currentActive.description}</p>
      </div>
    </div>
  )
}

方案说明

  • 方案1仅对原有jQuery代码做生命周期适配,后续如果组件出现重渲染,依然可能出现DOM被覆盖、类名丢失的问题,只适合临时快速修复
  • 方案2完全遵循React数据驱动视图的设计理念,没有原生DOM操作,不存在和虚拟DOM的冲突问题,逻辑清晰易维护,是Next.js项目下的首选实现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:33:14