jQuery多组dynamic_titles区块类循环切换异常求助
问题排查与修复
问题背景
页面包含两个结构相同的.dynamic_titles区块,每个区块内有多个.dynamic_title子元素,初始状态下一个为active,其余为inactive。需求是让每个区块独立循环切换子元素的active/inactive类,同时同步更新区块宽度为当前active子元素的宽度。但当前代码在多区块时互相干扰,且仅运行一次后停止。
页面结构示例:
<div class="dynamic_titles"> <div class="dynamic_title active">text 1</div> <div class="dynamic_title inactive">text 2</div> <div class="dynamic_title inactive">text 3</div> <div class="dynamic_title inactive">text 4</div> <div class="dynamic_title inactive">text 5</div> </div> <div class="dynamic_titles"> <div class="dynamic_title active">text 6</div> <div class="dynamic_title inactive">text 7</div> <div class="dynamic_title inactive">text 8</div> <div class="dynamic_title inactive">text 9</div> <div class="dynamic_title inactive">text 10</div> </div>
错误代码问题分析
当前代码的核心问题有三个:
this指向错误:setTimeout的回调函数内,this不再指向当前.dynamic_titles区块,而是指向全局对象(浏览器中为window),导致无法正确操作目标元素。- 全局变量污染:
widthTitle未用var/let声明,成为全局变量,多区块时会互相覆盖值。 - 冗余定时器:切换类和更新宽度的逻辑分开用两个定时器,容易出现不同步问题,且没必要重复设置定时器。
修复后的代码
$('.dynamic_titles').each(function () { // 保存当前区块的jQuery对象,避免this指向混乱 const $container = $(this); let index = 1; const max = $container.find('.dynamic_title').length; // 初始化宽度 let widthTitle = $container.find('.dynamic_title.active').width(); $container.css('width', widthTitle); function updateActiveAndWidth() { setTimeout(function () { // 切换active/inactive类 $container.find('.active').removeClass('active').addClass('inactive'); index++; if (index > max) { index = 1; } const $newActive = $container.find('.dynamic_title:nth-of-type(' + index + ')'); $newActive.addClass('active').removeClass('inactive'); // 更新容器宽度 widthTitle = $newActive.width(); $container.css('width', widthTitle); // 递归调用,实现循环 updateActiveAndWidth(); }, 3000); } updateActiveAndWidth(); });
修复关键点说明
- 固定
this指向:用const $container = $(this);将当前区块的jQuery对象保存到变量中,在定时器回调内直接使用该变量,避免this指向错误。 - 局部变量声明:用
let/const声明index、max、widthTitle,确保每个区块的变量独立,不会互相干扰。 - 合并逻辑:将切换类和更新宽度的逻辑合并到一个定时器函数中,保证操作同步,减少冗余代码。
内容的提问来源于stack exchange,提问作者Sergey Pervushin
相关产品推荐
相关产品推荐

