多选列表框中JavaScript仅移动每隔一个选中项的问题排查
多选列表移动问题修复
问题根源
sourceSelect.selectedOptions是动态的HTML元素集合,当你把选项从源列表移走后,这个集合会实时缩减——被移除的元素会直接从集合里消失。比如选中0-9这10个选项,第一次循环移走索引0的元素(0),集合长度变成9,原本索引1的元素(1)自动变成了索引0,而循环变量i此时变成1,会直接取集合里索引1的元素(也就是原来的2),就这样跳过了一半元素,最终只移走了偶数位的选项。
两种修复方法
方法一:转成静态数组
把动态集合转换成普通数组,切断和原列表的关联,这样循环时就不会因为集合变化而错位:
function moveSelectedPlayers(direction) { var sourceSelect, targetSelect; if (direction === 'right') { sourceSelect = document.getElementById('available_players'); targetSelect = document.getElementById('selected_players'); } else if (direction === 'left') { sourceSelect = document.getElementById('selected_players'); targetSelect = document.getElementById('available_players'); } // 把动态集合转成静态数组 var selectedOptions = Array.from(sourceSelect.selectedOptions); for (var i = 0; i < selectedOptions.length; i++) { targetSelect.appendChild(selectedOptions[i]); } }
如果要兼容老式浏览器(不支持Array.from),可以换成:
var selectedOptions = Array.prototype.slice.call(sourceSelect.selectedOptions);
方法二:反向循环
从最后一个选中项往前遍历,这样前面的元素被移除后,不会影响还没遍历到的元素索引:
function moveSelectedPlayers(direction) { var sourceSelect, targetSelect; if (direction === 'right') { sourceSelect = document.getElementById('available_players'); targetSelect = document.getElementById('selected_players'); } else if (direction === 'left') { sourceSelect = document.getElementById('selected_players'); targetSelect = document.getElementById('available_players'); } var selectedOptions = sourceSelect.selectedOptions; // 从最后一项开始往前循环 for (var i = selectedOptions.length - 1; i >= 0; i--) { targetSelect.appendChild(selectedOptions[i]); } }
额外修正
你的PHP代码里有个引号错误,输出option标签时,value的闭合引号写成了",会导致value值格式错误,修正后的代码:
echo '<option value="' . $row['player_id'] . '">' . $row['last_name'] . ', ' . $row['first_name'] . '</option>';
内容的提问来源于stack exchange,提问作者Chip Sharp
相关产品推荐
相关产品推荐

