jQuery中如何按顺序显示选中DOM元素?编号混乱问题排查
问题排查:随机选取DOM元素后编号显示不一致
问题描述
需要处理一组DOM元素,逻辑为先隐藏所有元素,通过类名获取元素组后随机选5个存入数组,再遍历数组按顺序给元素编号并显示,但最终显示的编号和预期不一致,想确定问题所在。
现有代码
JavaScript 代码
$(document).ready(function () { var elems = $(".test"); var items_ = []; for (var i = 0; (i < 5) && (i < elems.length); i++) { var r = Math.floor(Math.random() * (elems.length - i)) + i; var res = elems[r]; elems[r] = elems[i]; elems[i] = res; items_.push(res) } $('.test').fadeOut('slow', function(){ $(items_).each(function (index) { $(this).find('.number_test').text(index + 1); $(this).fadeIn('slow') }); }) })
HTML 代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <div class="test">First - <span class="number_test"></span></div> <div class="test">Second - <span class="number_test"></span></div> <div class="test">Third - <span class="number_test"></span></div> <div class="test">Fourth - <span class="number_test"></span></div> <div class="test">Fifth - <span class="number_test"></span></div> <div class="test">Sixth - <span class="number_test"></span></div> <div class="test">Seventh - <span class="number_test"></span></div> <div class="test">Eighth - <span class="number_test"></span></div> <div class="test">Ninth - <span class="number_test"></span></div> <div class="test">Tenth - <span class="number_test"></span></div>
问题根源
不是遍历顺序错误,核心问题有两个:
- 直接修改jQuery对象的类数组结构:
$(".test")返回的是jQuery对象,它是类数组但并非原生数组,直接用elems[r] = elems[i]修改会破坏jQuery对象内部的一致性,导致存入items_的元素出现异常关联。 - jQuery对象自动排序:
$(items_)将DOM元素数组转为jQuery对象时,jQuery会自动按照DOM文档中的原始顺序重新排列这些元素,完全忽略了你数组里的随机顺序,遍历自然会打乱编号逻辑。
修复方案
方案1:转原生数组操作,遍历原数组
先把jQuery对象转为原生DOM元素数组,操作数组时不会破坏结构,遍历直接用原生forEach保留顺序:
$(document).ready(function () { // 转为原生DOM元素数组 var elems = $(".test").toArray(); var items_ = []; for (var i = 0; (i < 5) && (i < elems.length); i++) { var r = Math.floor(Math.random() * (elems.length - i)) + i; var res = elems[r]; // 交换数组元素,原生数组操作无问题 elems[r] = elems[i]; elems[i] = res; items_.push(res); } $('.test').fadeOut('slow', function(){ // 直接遍历原生数组,保留随机顺序 items_.forEach(function(item, index) { $(item).find('.number_test').text(index + 1); $(item).fadeIn('slow'); }); }); })
方案2:使用jQuery的$.each遍历原数组
如果习惯用jQuery方法,用$.each直接遍历原生数组,避免转jQuery对象时的自动排序:
$(document).ready(function () { var elems = $(".test").toArray(); var items_ = []; for (var i = 0; (i < 5) && (i < elems.length); i++) { var r = Math.floor(Math.random() * (elems.length - i)) + i; var res = elems[r]; elems[r] = elems[i]; elems[i] = res; items_.push(res); } $('.test').fadeOut('slow', function(){ // $.each遍历原生数组,保留顺序 $.each(items_, function(index, item) { $(item).find('.number_test').text(index + 1); $(item).fadeIn('slow'); }); }); })
内容的提问来源于stack exchange,提问作者Studlara
相关产品推荐
相关产品推荐

