关于javascript:在保留当前所选项目的同时,按值对Html Select的选项进行排序的最有效方法是什么?

关于javascript:在保留当前所选项目的同时,按值对Html Select的选项进行排序的最有效方法是什么?

What is the most efficient way to sort an Html Select's Options by value, while preserving the currently selected item?

我有jQuery,但不确定是否有内置的排序助手。 我可以为每个项目的textvalueselected属性制作一个二维数组,但我认为Array.sort()内置的javascript不能正常工作。


将选项提取到一个临时数组中,进行排序,然后重建列表:

1
2
3
4
5
6
7
8
9
10
11
var my_options = $("#my_select option");
var selected = $("#my_select").val();

my_options.sort(function(a,b) {
    if (a.text > b.text) return 1;
    if (a.text < b.text) return -1;
    return 0
})

$("#my_select").empty().append( my_options );
$("#my_select").val(selected);

Mozilla的排序文档(特别是compareFunction)和Wikipedia的"排序算法"页面相关。

如果要使排序不区分大小写,请将text替换为text.toLowerCase()

上面显示的排序功能说明了如何进行排序。准确地对非英语语言进行排序可能很复杂(请参阅Unicode排序规则算法)。在sort函数中使用localeCompare是一个很好的解决方案,例如:

1
2
3
my_options.sort(function(a,b) {
    return a.text.localeCompare(b.text);
});

略微修改了汤姆的答案,以便实际上修改要排序的选择框的内容,而不仅仅是返回已排序的元素。

1
$('#your_select_box').sort_select_box();

jQuery函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$.fn.sort_select_box = function(){
    // Get options from select box
    var my_options = $("#" + this.attr('id') + ' option');
    // sort alphabetically
    my_options.sort(function(a,b) {
        if (a.text > b.text) return 1;
        else if (a.text < b.text) return -1;
        else return 0
    })
   //replace with sorted my_options;
   $(this).empty().append( my_options );

   // clearing any selections
   $("#"+this.attr('id')+" option").attr('selected', false);
}


我刚刚将Mark的想法包装在jquery函数中

1
$('#your_select_box').sort_select_box();

jQuery函数:

1
2
3
4
5
6
7
8
9
$.fn.sort_select_box = function(){
    var my_options = $("#" + this.attr('id') + ' option');
    my_options.sort(function(a,b) {
        if (a.text > b.text) return 1;
        else if (a.text < b.text) return -1;
        else return 0
    })
   return my_options;
}

我在对@Juan Perez的评论中提到的解决方案

1
2
3
4
5
6
7
8
9
$.fn.sortOptions = function(){
    $(this).each(function(){
        var op = $(this).children("option");
        op.sort(function(a, b) {
            return a.text > b.text ? 1 : -1;
        })
        return $(this).empty().append(op);
    });
}

用法:

1
$("select").sortOptions();

仍然可以对此进行改进,但是我不需要再添加其他铃声了:)


有一种封闭的jQuery票证,该票证应该可以使用,但它不包含在核心中。

1
2
3
jQuery.fn.sort = function() {
  return this.pushStack( [].sort.apply( this, arguments ), []);
};

从Google网上论坛线程引用,我认为您只是传入了一个用于排序的函数,就像这样

1
2
3
4
5
function sortSelect(selectToSort) {
    jQuery(selectToSort.options).sort(function(a,b){
        return a.value > b.value ? 1 : -1;
    });
}

希望能帮助到你!


好吧,在IE6中,它似乎在嵌套数组的[0]项目上进行了排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function sortSelect(selectToSort) {
    var arrOptions = [];

    for (var i = 0; i < selectToSort.options.length; i++)  {
        arrOptions[i] = [];
        arrOptions[i][0] = selectToSort.options[i].value;
        arrOptions[i][1] = selectToSort.options[i].text;
        arrOptions[i][2] = selectToSort.options[i].selected;
    }

    arrOptions.sort();

    for (var i = 0; i < selectToSort.options.length; i++)  {
        selectToSort.options[i].value = arrOptions[i][0];
        selectToSort.options[i].text = arrOptions[i][1];
        selectToSort.options[i].selected = arrOptions[i][2];
    }
}

我会看看这在其他浏览器中是否可行...

编辑:它也可以在Firefox中使用,呜呼!

有没有比这更简单的方法了?是否有某种内置在javascript或jQuery中的方法对我所缺少的选择进行排序,或者这是最好的方法?


这是一个更好的解决方案。
向JQuery声明全局函数

1
2
3
4
5
6
7
$.fn.sortSelect = function() {
    var op = this.children("option");
    op.sort(function(a, b) {
        return a.text > b.text ? 1 : -1;
    })
    return this.empty().append(op);
}

并从代码中调用该函数。

1
$("#my_select").sortSelect();

Array.sort()默认将每个元素转换为字符串,然后比较这些值。因此["value","text","selected"]被排序为"value, text, selected"。大多数时候,这可能会很好地工作。

如果确实要对值进行排序,或者将值解释为数字,则可以将比较函数传递给sort():

1
arrOptions.sort(function(a,b) { return new Number(a[0]) - new Number(b[0]); });

切记:如果要使用上下文选择器,则仅连接ID将不起作用

1
2
3
4
5
6
7
8
9
10
11
12
$.fn.sort_select_box = function(){
    var my_options = $("option", $(this));
    my_options.sort(function(a,b) {
        if (a.text > b.text) return 1;
        else if (a.text < b.text) return -1;
        else return 0
    });
    $(this).empty().append(my_options);
}

// Usando:
$("select#ProdutoFornecedorId", $($context)).sort_select_box();

推荐阅读