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

如何实现动态金字塔中区块按1-9、a-z规则排序显示?

嘿,我看到你在动态金字塔的区块排序上碰到了麻烦,这事儿其实是JavaScript默认的排序逻辑在搞鬼,咱们一步步解决它:

问题根源

你用的values.sort()是按字符串的Unicode码点来排序的,比如"6g"里的"6" Unicode值是54,比"4p"里的"4"(52)大,所以默认排序会把"6g"放在"4p"前面,这完全不符合你想要的「先按1-9数字排序,数字相同再按a-z字母排序」的规则。另外,你之前只排序了数组,但没同步更新页面上的DOM元素顺序,所以页面显示还是添加区块的原始顺序。

解决方案

咱们要做两件核心的事:自定义排序规则,然后让DOM和排序后的数组保持同步。

1. 写一个符合需求的排序函数

把你代码里的values.sort()替换成下面这个自定义比较函数,它会先比较数字部分,数字相同再比字母:

function compareBlocks(a, b) {
    // 提取每个名称的数字部分,转成数字类型
    const numA = parseInt(a.name.charAt(0), 10);
    const numB = parseInt(b.name.charAt(0), 10);
    
    // 数字不同时,小的在前
    if (numA !== numB) {
        return numA - numB;
    }
    // 数字相同时,按字母顺序排序(用localeCompare能保证正确的字母排序)
    return a.name.slice(1).localeCompare(b.name.slice(1));
}

// 用自定义函数排序数组
values.sort(compareBlocks);

2. 让页面显示和数组同步

光排序数组没用,页面上的区块还是原来的顺序,所以咱们需要一个渲染函数,每次添加/删除区块后,根据排序后的数组重新生成页面上的金字塔:

首先,添加这个渲染函数:

function renderPyramid() {
    // 先清空现有的金字塔列表
    $('.pyramid').empty();
    
    // 遍历排序后的数组,逐个创建区块
    values.forEach(blockInfo => {
        // 把区块的所有信息(名称、颜色、宽度、输入值)整合渲染
        const $block = $(`<li><div class="item" style="width:${blockInfo.width}px; border-bottom: 60px solid ${blockInfo.color} ;"><input class="values" type="text" placeholder="${blockInfo.name}" maxlength="2" value="${blockInfo.value}"></div></li>`);
        
        // 保存用户修改的输入值,避免渲染后丢失
        $block.find('.values').on('input', function() {
            blockInfo.value = $(this).val();
        });
        
        $('.pyramid').append($block);
    });
}

3. 修改添加和删除逻辑

原来的代码是直接append区块,现在要改成存储区块的完整信息,然后排序后调用渲染函数:

  • 添加区块的修改:把原来的字符串存储改成对象存储,包含所有需要的信息,再排序渲染:
// 把区块的所有信息存在对象里,方便后续渲染
const newBlock = {
    name: number + resultLetter,
    color: resultColor,
    width: plus,
    value: "" // 用来存用户输入的内容
};

values.push(newBlock);
values.sort(compareBlocks);
renderPyramid(); // 调用渲染函数更新页面
console.log(values);
  • 删除区块的修改:直接删除数组最后一项后调用渲染函数,不用再手动操作DOM:
$('#remove-block .button').click(function() {
    if (values.length === 0) return; // 防止数组为空时报错
    values.pop(); // 直接删除最后一项,比splice更简洁
    renderPyramid();
    console.log(values);
})

完整的修改后JS代码

$(document).ready(function() {
 //Add Block Functionality
 let values = [];

 // 自定义区块排序函数
 function compareBlocks(a, b) {
     const numA = parseInt(a.name.charAt(0), 10);
     const numB = parseInt(b.name.charAt(0), 10);
     if (numA !== numB) {
         return numA - numB;
     }
     return a.name.slice(1).localeCompare(b.name.slice(1));
 }

 // 渲染金字塔的函数
 function renderPyramid() {
     $('.pyramid').empty();
     values.forEach(blockInfo => {
         const $block = $(`<li><div class="item" style="width:${blockInfo.width}px; border-bottom: 60px solid ${blockInfo.color} ;"><input class="values" type="text" placeholder="${blockInfo.name}" maxlength="2" value="${blockInfo.value}"></div></li>`);
         $block.find('.values').on('input', function() {
             blockInfo.value = $(this).val();
         });
         $('.pyramid').append($block);
     });
 }

 $('#add-block .button').click(function() {
     var lastwidth = $('.pyramid li:last-child .item').width();
     var plus = lastwidth == null ? 90 : lastwidth + 190;
     
     var number = Math.floor(Math.random() * 9) + 1;
     function randLetter() {
         var letters = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];
         return letters[Math.floor(Math.random() * letters.length)];
     }
     var resultLetter = randLetter();
     
     function randColor() {
         var colors = ["green", "yellowgreen", "Chocolate", "goldenrod", "cadetblue", "firebrick", "magenta", "LightSeaGreen", "Peru", "Sienna", "SlateBlue", "Snow", "Tan", "Skyblue"];
         return colors[Math.floor(Math.random() * colors.length)];
     }
     var resultColor = randColor();

     const newBlock = {
         name: number + resultLetter,
         color: resultColor,
         width: plus,
         value: ""
     };

     values.push(newBlock);
     values.sort(compareBlocks);
     renderPyramid();
     console.log(values);
 });

 //Remove Block Functionality
 $('#remove-block .button').click(function() {
     if (values.length === 0) return;
     values.pop();
     renderPyramid();
     console.log(values);
 })
});

这样修改后,每次添加区块都会自动按「数字1-9优先,同数字下字母a-z」的规则排列,而且还能保留每个区块的颜色和用户输入的内容,不会每次渲染都重置啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:36:13