【问题标题】:Sorting list of elements in JQueryJQuery中元素的排序列表
【发布时间】:2012-01-16 01:10:32
【问题描述】:

我有一个使用 JQuery 获得的元素列表。

var $self = $(this);
var $fields = $('.identifier-controls', $self);

此列表是在控件呈现时需要以某种方式操作的元素列表。 $fields 列表中的每个元素都包含一个名为“data-order”的数据属性。这个属性告诉我应该在控件中以什么顺序排列元素(啊要求)。顺序不必是直接线性顺序(意味着第一个控件可以有一个属性值 10,下一个 15 和下一个 17 等。它们只需要按 asc 顺序出现。有没有简单的实现这一点的方法?我能想出的所有方法似乎都有些过于复杂了。

【问题讨论】:

    标签: jquery sorting elements


    【解决方案1】:

    按数据属性对 jquery“类数组”对象进行排序的步骤...

    1. 通过 jquery 选择器选择所有对象
    2. 转换为实际数组(不是类似数组的 jquery 对象)
    3. 对对象数组进行排序
    4. 使用 dom 对象数组转换回 jquery 对象

    HTML

    2
    1
    4
    3

    纯 jquery 选择器

    $('.item');
    
    [
    2
    ,
    1
    ,
    4
    ,
    3
    ]

    让我们按数据顺序排序

    函数 getSorted(selector, attrName) {
        return $($(selector).toArray().sort(function(a, b){
            var aVal = parseInt(a.getAttribute(attrName)),
                bVal = parseInt(b.getAttribute(attrName));
            返回 aVal - bVal;
        }));
    }
    > getSorted('.item', 'data-order')
    
    [
    1
    ,
    2
    ,
    3
    ,
    4
    ]

    See how getSorted() works.

    希望这会有所帮助!

    【讨论】:

    • 博文不见了:-(
    【解决方案2】:

    试试这个:

    $(function(){
       var $self = $(this);
       var sortedList = $('.identifier-controls', $self).sort(function(lhs, rhs){
          return parseInt($(lhs).attr("data-order"),10) - parseInt($(rhs).attr("data-order"),10);
       });
    });
    

    变量 sortedList 现在具有已排序的元素。

    【讨论】:

    • @TheSheekGeek:请参阅我对其他答案之一的说明,只要您知道您依赖于随时可能改变的无证行为,并且您正在处理jQuery 存储元素的顺序,这将产生连锁反应,因为许多 jQuery 方法保证事情将以特定的顺序完成。 (我也没有看到这如何在 DOM 中移动;这不是必需的吗?)
    • 控件的另一部分中有代码处理将它们添加到 DOM。控件实际上所做的是获取一堆已经存在的文本框和标签(只是 li 元素的列表)并窃取它们,将它们添加回 DOM 以创建一个看起来像下拉列表的控件,其中包含所有文本框。需求的喜悦。 (其实还不错)
    【解决方案3】:

    类似:

    $fields.sort(function(a, b) {
        return a.getAttribute('data-order') > b.getAttribute('data-order');
    }).appendTo($fields.parent());
    

    小提琴:http://jsfiddle.net/gCFzc/

    【讨论】:

    • jQuery 对象是 not 数组。它们类似于数组。 jQuery 对象的sort 函数未记录在案,如果您查看 jQuery.js 文件,他们会说它仅供内部使用。因此,需要注意的是。也就是说,如果你确定 jQuery 不会因为你弄乱其元素的顺序而搞砸(我不是),你可以手动将 Array.prototype.sort 应用到它; the spec 很清楚,您应该能够在类似数组的非数组对象上使用它。请注意,一旦对它进行排序,它们仍然会显示在 DOM 中的相同位置。
    • @T.J.Crowder 部分 jQuery 开发人员的错误设计决定将其称为排序并使选择器结果类似于数组。很多打鸭子的 js 程序员都会掉进这个陷阱。
    【解决方案4】:

    插入排序是一种相当直接的方式。

    或者有点颠覆性,你可以利用 JavaScript 引擎来实现这一点:

    var $fields, $container, sorted, index;
    
    $container = $('body');
    $fields = $("div[data-order]", $container);
    sorted = [];
    $fields.detach().each(function() {
        sorted[parseInt(this.getAttribute("data-order"), 10)] = this;
    });
    sorted.forEach(function(element) {
        $container.append(element);
    });
    

    实例:

    (function($) {
        var $fields, $container, sorted, index;
      
        $container = $('body');
        $fields = $("div[data-order]", $container);
        sorted = [];
        $fields.detach().each(function() {
            sorted[parseInt(this.getAttribute("data-order"), 10)] = this;
        });
        sorted.forEach(function(element) {
            $container.append(element);
        });
    })(jQuery);
    <div data-order="30">30</div>
    <div data-order="40">40</div>
    <div data-order="10">10</div>
    <div data-order="20">20</div>
    <div data-order="1">1</div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

    这是如何工作的:

    • 我们获取容器,并从中获取字段。

    • 我们创建一个空白数组。请记住 JavaScript 数组 aren't really arrays at all,它们本质上是稀疏的。

    • 我们分离字段,然后循环遍历它们,从 DOM 元素中获取 data-order 并将 DOM 元素添加到该位置的数组中。这假定 data-order 值是唯一的。

    • 一旦我们有了原始 DOM 元素的数组,我们使用 forEach 循环遍历它,将它们附加到容器中。我没有使用jQuery.each,因为jQuery.each 即使对于不存在的数组索引也会调用回调,如果您的data-order 值非常稀疏,这可能是个问题。 forEach 按数字顺序迭代条目,跳过不存在的条目。

    【讨论】:

    • 感谢它对我的工作几乎没有修改。
    猜你喜欢
    • 2012-12-24
    • 2011-03-04
    • 2015-11-28
    • 2018-05-08
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    • 2020-08-16
    • 1970-01-01
    相关资源
    最近更新 更多