如何按姓氏对含HTML标签的<li>列表项排序且不修改原项?
按姓氏排序带HTML标签的列表项(不修改原项)
可以实现,核心是利用JavaScript的sort方法自定义比较逻辑,提取每个列表项中的姓氏作为排序依据,仅调整元素在DOM中的位置,完全保留原项的HTML结构和内容。
具体实现步骤与代码:
- 获取目标列表项:将DOM中的列表项转为数组,方便使用数组方法。
- 自定义排序规则:从每个列表项的文本内容中提取姓氏,以此为基准排序。
- 重新排列DOM元素:将排序后的列表项重新插入到父容器中,完成排序。
// 1. 获取所有带目标class的列表项,转为数组 const listItems = Array.from(document.querySelectorAll('.sortable-itemW5')); // 2. 按姓氏排序的自定义比较函数 listItems.sort((itemA, itemB) => { // 提取并清理文本内容 const textA = itemA.textContent.trim(); const textB = itemB.textContent.trim(); // 拆分文本为片段(适配你的"名 中间名. 姓 编号"格式) const segmentsA = textA.split(/\s+/); const segmentsB = textB.split(/\s+/); // 提取姓氏:根据你的示例,姓氏是倒数第二个片段(最后一个是编号) const lastNameA = segmentsA[segmentsA.length - 2]; const lastNameB = segmentsB[segmentsB.length - 2]; // 大小写不敏感的字母排序 return lastNameA.localeCompare(lastNameB, undefined, { sensitivity: 'base' }); }); // 3. 找到列表的父容器(根据实际DOM结构调整选择器,比如ul/ol) const parentContainer = document.querySelector('ul'); // 清空父容器后重新添加排序后的项(原项结构完全保留) parentContainer.innerHTML = ''; listItems.forEach(item => parentContainer.appendChild(item));
注意事项:
- 如果你的列表项格式有变化(比如部分项没有编号),需要调整提取姓氏的逻辑:
- 若为纯"名 姓"格式,直接取
segments[1]作为姓氏即可。
- 若为纯"名 姓"格式,直接取
localeCompare方法支持多语言排序,比直接字符串比较更可靠,sensitivity: 'base'确保大小写不影响排序结果。
内容的提问来源于stack exchange,提问作者Larry Tate
相关产品推荐
相关产品推荐

