JS/jQuery新增单选按钮后按label文本排序列表问题修复
修复方案
问题原因
- 选择器错误:HTML里相册列表用的是id
album-list,新增元素时用class选择器.album-list查找,无法匹配到目标容器 - DOM节点逻辑错误:单个DOM节点同一时间只能在页面存在一个位置,仅创建1个label节点就追加到所有下拉容器,会导致节点被反复移动,最终只有最后一个容器能显示新增选项
- 重复id违规:每个下拉菜单都使用了相同id
album-list,id是页面全局唯一属性,重复使用会导致选择器只能命中第一个元素 - 排序逻辑缺陷:仅对第一个列表执行排序,且
empty()方法会清空所有子元素,把预留的.added-dropdown-select容器一并删除;排序时取整个label的文本,会包含关闭按钮等无关内容,导致排序结果错误
修复操作
- 修改HTML:将所有
<div id='album-list'>改为<div class='album-list'>,删除重复id,统一用class匹配所有下拉列表 - 修正新增逻辑:遍历每个列表容器时,单独创建属于当前容器的label节点,避免节点复用问题
- 重写排序逻辑:遍历所有相册列表单独排序,排序时仅处理相册选项label,排序完成后将选项插回预留容器之前,保留原有结构不被破坏
修复代码
HTML调整部分
仅需修改列表容器的属性,其余结构保持不变:
<div class='album-dropdown-content'> <label class='album-select new-album-select'>New Album <input type='radio' name='new_album_radio' class='new-album-radio'/> <span class='checkmark'></span> <input type='text' name='new_album' class='new-album-text' id='txt-<?= esc($row->viewkey); ?>'/> <button class='new-album-button' data-viewkey='<?= $row->viewkey; ?>'>Create</button> </label> <!-- 原id="album-list" 改为class="album-list" --> <div class='album-list'> <?php if (! empty($albums)) { foreach ($albums as $album) { ?> <label class='album-select'> <?= esc($album->album_name); ?> <i class="fa-solid fa-xmark" data-viewkey='<?= esc($row->viewkey); ?>' data-album='<?= esc($row->album_name); ?>'></i> <input type='radio' name='album_radio' value='<?= $album->album_name; ?>' class='album-radio' data-viewkey='<?= esc($row->viewkey); ?>'/> <span class='checkmark'></span> </label> <?php }} ?> <div class='added-dropdown-select'> <!-- Javascript generates album radio dropdown list --> </div> </div> </div>
JavaScript修复后代码
function addNewRadioItem(viewkey, albumName) { const containers = document.querySelectorAll('.album-list'); containers.forEach(container => { // 每个容器单独创建节点,禁止复用同一个DOM节点 const label = document.createElement('label'); const input = document.createElement('input'); const span = document.createElement('span'); const closeIcon = document.createElement('i'); label.className = 'album-select'; label.append(albumName); // 组装关闭按钮 closeIcon.className = 'fa-solid fa-xmark'; closeIcon.dataset.viewkey = viewkey; closeIcon.dataset.albumname = albumName; label.append(closeIcon); // 组装单选框 input.type = 'radio'; input.name = 'album_radio'; input.className = 'album-radio'; input.value = albumName; input.dataset.viewkey = viewkey; input.defaultChecked = true; label.append(input); // 组装选中标记 span.className = 'checkmark'; label.append(span); container.append(label); }); // 所有节点追加完成后执行全量排序 sortAllAlbumLists(); } function sortAllAlbumLists() { document.querySelectorAll('.album-list').forEach(albumList => { // 仅提取相册选项节点,过滤其他容器元素 const listItems = Array.from(albumList.querySelectorAll('label.album-select')); const placeholder = albumList.querySelector('.added-dropdown-select'); // 直接取单选框的value做排序依据,避免无关文本干扰 listItems.sort((a, b) => { const nameA = a.querySelector('.album-radio').value.toUpperCase(); const nameB = b.querySelector('.album-radio').value.toUpperCase(); return nameA.localeCompare(nameB); }); // 排序后依次插入到预留容器前,不破坏原有DOM结构 listItems.forEach(item => { albumList.insertBefore(item, placeholder); }); }); }
内容的提问来源于stack exchange,提问作者Programming_Squirrel
相关产品推荐
相关产品推荐

