如何用JavaScript根据数值内容重新排序并追加HTML元素?
问题:根据数值内容对Div进行降序排序
我正在开发一款应用,需要将HTML div根据其数值内容降序排列。目前已实现输入数值后排序并对应到div的功能,但发现每次新增条目时,仅数值位置变化,div实际顺序未改变。希望将数值内容与其所属div关联,实现div的排序而非仅数值排序。问题出在JS代码后半部分。
HTML代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Order Divs</title> <link rel="stylesheet" href="style.css"> </head> <body> <input type="number" id="point-input"> <button id="sub-btn">Submit</button> <button id="order">Order Button</button> <button id="add-btn">Add</button> <div id="container"></div> <script src="main.js"></script> </body> </html>
JavaScript代码(原代码)
//variables below let orderBtn=document.getElementById("order") console.log(orderBtn) let addBtn=document.getElementById("add-btn") console.log(addBtn) const container=document.getElementById("container") console.log(container) let numArr=[] let numInc=1 let numToBeRe=[] let child=document.getElementsByClassName(`child${numInc}`) console.log(`child${numInc}`) let subBtn=document.getElementById("sub-btn") console.log(subBtn) let pointInput=document.getElementById("point-input") console.log(pointInput) let numbers=document.querySelector(".numbers") console.log(numbers) //adding an event lister to the submit button below subBtn.addEventListener("click",()=>{ let pointInput=document.getElementById("point-input") console.log(pointInput.value) numToBeRe.push(pointInput.value) //push the input field value to an array console.log(numToBeRe) // console.log(typeof(pointInput.value)) pointInput=parseInt(pointInput.value) console.log(pointInput) console.log(numToBeRe) numToBeRe.sort(function(a,b){return b-a}) console.log(numToBeRe) let hp=0; let name=""; let weapns=""; //Adding html literals on the onclick // I think the problem is below here container.innerHTML+= `<span class="child${numInc} child"> <div class="numbers"></div> <div class="name-display"></div> <input class="name-input"> <button class="name-sub-btn">Submit</button> <div class="hp-display"></div> <input class="hp-input"> <button class="hp-sub-btn">Submit</button> <div class="weapons-display"></div> <input class="weapons-input"> <button class="weapons-sub-btn">Submit</button> </span>` numInc=numInc+1 // console.log(`child${numInc}`) empty() let numbers=document.querySelectorAll(".numbers") console.log(numbers) for(let i=0;i<numbers.length;i++){ console.log(numbers[i]) for(let i=0;i<numToBeRe.length;i++){ console.log(numToBeRe[i]) numbers[i].innerText=numToBeRe[i]; }}
问题根源
你当前的逻辑是单独维护数值数组numToBeRe,排序后仅将数值重新赋值给所有.numbers元素,但并未改变这些元素所在父容器(.child span)的顺序,导致仅数值显示变化,div实际位置未动。
修复方案
核心思路:将每个条目(包含数值、名称、HP、武器等信息)作为整体数据对象管理,而非单独存储数值数组。排序时基于数据对象的数值排序,再重新渲染容器内容或直接调整DOM顺序。
具体修改步骤
替换原数值数组,用数组存储每个条目的完整数据:
// 替换原numToBeRe数组 let items = [];修改提交按钮的事件逻辑,将数据存入数组并排序:
在subBtn的点击事件中,替换原push逻辑:subBtn.addEventListener("click", () => { const pointInput = document.getElementById("point-input"); const value = parseInt(pointInput.value); // 校验输入是否为有效数字 if (!isNaN(value)) { // 添加完整条目数据 items.push({ id: numInc, value: value, name: "", hp: 0, weapons: "" }); // 按数值降序排序 items.sort((a, b) => b.value - a.value); numInc++; // 重新渲染所有条目 renderItems(); // 清空输入框 pointInput.value = ""; } });实现
renderItems函数,根据排序后的数组渲染DOM:function renderItems() { container.innerHTML = ""; // 先清空容器 items.forEach(item => { container.innerHTML += ` <span class="child${item.id} child"> <div class="numbers">${item.value}</div> <div class="name-display">${item.name}</div> <input class="name-input" placeholder="输入名称"> <button class="name-sub-btn" data-id="${item.id}">Submit</button> <div class="hp-display">${item.hp}</div> <input class="hp-input" placeholder="输入HP" type="number"> <button class="hp-sub-btn" data-id="${item.id}">Submit</button> <div class="weapons-display">${item.weapons}</div> <input class="weapons-input" placeholder="输入武器"> <button class="weapons-sub-btn" data-id="${item.id}">Submit</button> </span> `; }); // 给新增的按钮绑定事件 bindItemButtons(); }实现
bindItemButtons函数,处理名称、HP、武器的提交:function bindItemButtons() { // 名称提交 document.querySelectorAll(".name-sub-btn").forEach(btn => { btn.addEventListener("click", function() { const id = parseInt(this.dataset.id); const input = this.previousElementSibling; const item = items.find(i => i.id === id); if (item) { item.name = input.value; renderItems(); // 重新渲染更新内容 } }); }); // HP提交 document.querySelectorAll(".hp-sub-btn").forEach(btn => { btn.addEventListener("click", function() { const id = parseInt(this.dataset.id); const input = this.previousElementSibling; const hpValue = parseInt(input.value); const item = items.find(i => i.id === id); if (item && !isNaN(hpValue)) { item.hp = hpValue; renderItems(); } }); }); // 武器提交 document.querySelectorAll(".weapons-sub-btn").forEach(btn => { btn.addEventListener("click", function() { const id = parseInt(this.dataset.id); const input = this.previousElementSibling; const item = items.find(i => i.id === id); if (item) { item.weapons = input.value; renderItems(); } }); }); }给排序按钮绑定事件(可选,若需要手动触发排序):
orderBtn.addEventListener("click", () => { items.sort((a, b) => b.value - a.value); renderItems(); });移除原代码中
numToBeRe数组及后续的数值赋值循环,因为现在渲染时直接从排序后的数组取值。
方案优势
- 数据与DOM通过
id关联,所有操作基于唯一的数据源(items数组),避免数据与DOM不同步的问题。 - 排序后重新渲染,自然改变div的实际顺序,完全满足需求。
内容的提问来源于stack exchange,提问作者SamBoone
相关产品推荐
相关产品推荐

