按字母数字顺序对一组li标签进行排序

3

我一直在尝试编写一个函数,按照它们的内容对li标签的选择进行排序,但目前没有成功(至少没有速度/准确性);

$('.sortasc').live('click',function(){

        var liArr = Array();

        $('#licontainer').children('li').each(function(){
           liArr.push($(this).html());
        });

        liArr.sort(alphaNumSort);

        $(liArr).each(function(){
            var current = this;

            var clone = $('li').filter(function(){return($(this).html()==current);}).clone();

            $('li').filter(function(){return($(this).html()==current);}).remove();

            clone.appendTo('#tempsortbox');

        });

        $('#licontainer').html($('#tempsortbox').html());
        $('#tempsortbox').html('')

    });

它既慢又不太擅长排序。理想情况下,它应该根据li中包含的strong标签的内容进行排序。

如果您有兴趣,这里是alphaNumSort函数(这个函数很好用,只是糟糕的html和克隆垃圾并没有真正起作用)

function alphaNumSort(m,n){
try{
    var cnt= 0,tem;
    var a= m.toLowerCase();
    var b= n.toLowerCase();
    if(a== b) return 0;
    var x=/^(\.)?\d/;

    var L= Math.min(a.length,b.length)+ 1;
    while(cnt< L && a.charAt(cnt)=== b.charAt(cnt) &&
    x.test(b.substring(cnt))== false && x.test(a.substring(cnt))== false) cnt++;
    a= a.substring(cnt);
    b= b.substring(cnt);

    if(x.test(a) || x.test(b)){
        if(x.test(a)== false)return (a)? 1: -1;
        else if(x.test(b)== false)return (b)? -1: 1;
        else{
            var tem= parseFloat(a)-parseFloat(b);
            if(tem!= 0) return tem;
            else tem= a.search(/[^\.\d]/);
            if(tem== -1) tem= b.search(/[^\.\d]/);
            a= a.substring(tem);
            b= b.substring(tem);
        }
    }
    if(a== b) return 0;
    else return (a >b)? 1: -1;
}
catch(er){
    return 0;
}

}

Cheers

3个回答

11

我不完全确定你的alphaNumSort函数是做什么的,但一个简单的字符串比较可能已经足够了。

var li = $('#licontainer li').get();

// sort the list items based on the contents of a nested strong tag
li.sort(function(a, b) {
    a = $('strong', a).text();
    b = $('strong', b).text();

    // you may want to process the text values further here, perhaps
    // running it through $.trim, reducing whitespace sequences with
    // a regular expression, or lower- or upper-casing letters to
    // make the comparison case-insensitive.

    return (a < b) ? -1 : ((a > b) ? 1 : 0);
});

// reinsert the list items in their new order
$('#licontainer').append(li);

这种方法应该比您的临时列表方法快得多,因为它执行的DOM操作较少。使用本地字符串比较也应该比您当前的排序算法快得多,但如果它执行了我错过的特定操作,请更新return语句以利用它(保留前面的行)。

return alphaNumSort(a, b);

如果这仍然太慢,您可以通过在操作列表之前隐藏它来进一步提高性能,从而防止浏览器执行不必要的重绘。

var li = $('#licontainer').hide().find('li').get();

// ...

$('#licontainer').append(li).show();

1
+1 innerText绝对比innerHTML更好。不过字符串可能仍需要一些处理,如果嵌套标记不一致,可以尝试修剪空格。另外,Array.sort是非标准的,应该使用Array.prototype.sort.call - bobince
感谢您的反馈和点赞。Array.sort 绝对是标准方法,但它肯定不如使用 Array.prototype 兼容。我会根据您的评论更新我的答案,并将文本后处理作为读者的练习 :) - Alex Barrett
1
在我看来,li.get().sort 更符合代码读者的直觉。 - Roatin Marth
谢谢Roatin Marth,我同意你的观点。我已经更新了答案并采用了你的建议。我在初始变量赋值中添加了get(),因为sort()是原地操作。 - Alex Barrett
这是个非常棒的小片段,能很好地完成任务。我实现了我的字母数字排序,可以将1、2、15、17、27按照正确顺序排序,而不是像1、15、17、2、27那样排序,同时还可以按照文本进行排序。代码行数只有5行,非常快速!非常感谢! - Joel

0
var sortList = function () {
    var ul = document.getElementsByTagName("ul"),
    ol = document.getElementsByTagName("ol"),
    sort = function (x) {
        var a, li;
        for (a = 0; a < x.length; a += 1) {
            li = x[a].getElementsByTagName("li");
            li = li.sort();
            x[a].innerHTML = li.join("");
        }
    };
    sort(ul);
    sort(ol);
};

0
如果你想用JavaScript对其进行排序,你需要一个用于排序的方法/函数。并且你需要选择何时进行排序:加载、点击按钮等等...
另一种可能性是在发送HTML之前进行排序:这取决于你的服务器语言。PHP、Java、ASP等等?但是你可以使用相同的链接来找到最适合你需求的最佳算法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接