jQuery使用each遍历收集数据push到数组及重复值问题排查
问题根源
- 你定义
cekslotid时没有加var/let/const关键字,导致它成为全局变量,每次任意.slot_id下拉触发change事件时,都会把这个变量覆盖为当前选中的下拉值 - 收集选中值的遍历逻辑错误:你在遍历所有
.slot_id元素时,使用了$(cekslotid).val()取值,这里cekslotid是选中值的字符串(比如G05B-IA2),不是DOM选择器,你根本没有取到当前遍历到的下拉元素的选中值,反而每次都重复插入了全局cekslotid的当前值,最终数组里全是重复内容 - 初始化
data数组时你已经插入了第一个slot_id的值,后续又遍历所有.slot_id元素插入值,逻辑重复,就算遍历逻辑写对了也会出现第一个值重复的问题
修复方案
1. 修正选中值收集逻辑
直接统一遍历所有.slot_id元素取值,不需要单独维护全局cekslotid变量:
// 仓库或托盘下拉变化时统一触发逻辑 $(document).on('change', '.warehouse2, .slot_id', function(){ // 遍历所有托盘下拉收集非空选中值 let selectedSlots = []; $('.slot_id').each(function() { const currentVal = $(this).val(); if(currentVal) selectedSlots.push(currentVal); }); console.log(selectedSlots); // 此处即可得到预期的无重复选中值数组 // 调用选项过滤方法,实现已选值不在其他下拉展示 filterSlotOptions(selectedSlots); });
2. 实现已选选项过滤功能
先在页面初始化时缓存全量托盘选项,再根据选中值过滤每个下拉的可选选项:
// 页面初始化时缓存全量托盘选项(默认第一个下拉加载完所有选项) const allSlotOptions = $('#slot_id option').map(function() { return { value: $(this).val(), text: $(this).text() }; }).get().filter(opt => opt.value); // 过滤掉空的默认选项 // 过滤所有下拉的可选选项 function filterSlotOptions(selectedSlots) { $('.slot_id').each(function() { const currentSelected = $(this).val(); // 生成当前下拉可选列表:排除已选值,但是保留当前下拉自身选中的值 const availableOptions = allSlotOptions.filter(opt => { return !selectedSlots.includes(opt.value) || opt.value === currentSelected; }); // 重新渲染当前下拉选项 $(this).empty().append('<option value="">-- Pilih Pallet --</option>'); availableOptions.forEach(opt => { const selectedAttr = opt.value === currentSelected ? 'selected' : ''; $(this).append(`<option value="${opt.value}" ${selectedAttr}>${opt.text}</option>`); }); }); }
注意事项
你动态新增表单区块后,要先给新生成的.slot_id下拉同步全量选项,再调用一次filterSlotOptions方法,保证新增下拉不会出现已经被选中的选项。
内容的提问来源于stack exchange,提问作者mfahmifadh
相关产品推荐
相关产品推荐

