You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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顺序。

具体修改步骤

  1. 替换原数值数组,用数组存储每个条目的完整数据:

    // 替换原numToBeRe数组
    let items = [];
    
  2. 修改提交按钮的事件逻辑,将数据存入数组并排序:
    在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 = "";
      }
    });
    
  3. 实现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();
    }
    
  4. 实现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();
          }
        });
      });
    }
    
  5. 给排序按钮绑定事件(可选,若需要手动触发排序):

    orderBtn.addEventListener("click", () => {
      items.sort((a, b) => b.value - a.value);
      renderItems();
    });
    
  6. 移除原代码中numToBeRe数组及后续的数值赋值循环,因为现在渲染时直接从排序后的数组取值。

方案优势

  • 数据与DOM通过id关联,所有操作基于唯一的数据源(items数组),避免数据与DOM不同步的问题。
  • 排序后重新渲染,自然改变div的实际顺序,完全满足需求。

内容的提问来源于stack exchange,提问作者SamBoone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 02:48:24