根据属性"data-sort"在jQuery中排序divs?

81
如果我有几个div:
<div data-sort='1'>div1</div>
<div data-sort='4'>div4</div>
<div data-sort='8'>div8</div>
<div data-sort='12'>div12</div>
<div data-sort='19'>div19</div>

我动态创建了这些 div:

<div data-sort='14'>div1</div>
<div data-sort='6'>div1</div>
<div data-sort='9'>div1</div>

如何让它们只按照已经加载的div的顺序进行排序,而无需重新加载所有的div?

我认为我需要构建一个包含屏幕上所有div的data-sort值的数组,然后查看新div适合哪个位置,但我不确定这是否是最好的方法。

4个回答

120

使用这个函数

   var result = $('div').sort(function (a, b) {

      var contentA =parseInt( $(a).data('sort'));
      var contentB =parseInt( $(b).data('sort'));
      return (contentA < contentB) ? -1 : (contentA > contentB) ? 1 : 0;
   });

   $('#mylist').html(result);

在添加新的div后,您可以立即调用此函数。

如果您想保留

元素内的JavaScript事件,请勿像上面的示例中那样使用HTML替换。而是使用以下方法:

$(targetSelector).sort(function (a, b) {
    // ...
}).appendTo($container);

19
这段代码似乎存在一个微妙的错误,因为它使用了 .attr('data-sort') 而不是 .data('sort')。如果页面上的 data-sort 值在动态更新,则 attr('data-sort') 仍将使用原始值。 - apb
1
@AndyB。你确定吗?你能提供一个出现此问题的示例/版本吗?我在这里测试过了,它可以正常工作:http://jsfiddle.net/fMe7R/1/ - danronmoon
2
@danronmoon 哦,是的,你说得对 - 结果我使用了 .attr 进行设置,然后尝试使用 .data 进行访问,这是两个不同的东西。 - apb
3
非常好,我使用它对包含术语的一堆UL元素进行排序。 $("#allTerms>ul").sort(function(a, b) { var contentA = parseInt($(a).attr('data-sort')); var contentB = parseInt($(b).attr('data-sort')); return (contentA < contentB) ? -1 : (contentA > contentB) ? 1 : 0; }).appendTo($("#allTerms")); - Magali
17
这里有一个需要注意的地方。sort方法只会返回已排序的列表,并不会就地对元素进行排序。你需要手动添加新列表,例如使用$('#mylist').html(result)。 - Johncl
显示剩余8条评论

30

我将其转换为jQuery函数:

jQuery.fn.sortDivs = function sortDivs() {
    $("> div", this[0]).sort(dec_sort).appendTo(this[0]);
    function dec_sort(a, b){ return ($(b).data("sort")) < ($(a).data("sort")) ? 1 : -1; }
}

你有一个类似于“#boo”的大div,里面有很多小的div:

$("#boo").sortDivs();

你需要加上"? 1 : -1"是因为Chrome浏览器中存在一个bug,如果没有它,就不能对超过10个div进行排序! http://blog.rodneyrehm.de/archives/14-Sorting-Were-Doing-It-Wrong.html


2
我有一个问题关于@PJBrunets的解决方案。之前位于父div中的div会发生什么?就我所理解的解决方案而言,我们只是将更多(排序后)的div添加到父级中,难道我们不需要删除“旧”的div吗? - Michaela.Merz
1
@Michaela.Merz 我认为它们已经在原地排序了,不需要删除任何东西。 但是我创建该函数已经有一段时间了,我不记得具体细节。 我曾像这样使用它与一个修改过的jquery.vgrid
$(“#grid-content”)。sortDivs(); window.vg = $(“#grid-content”)。vgrid();
- PJ Brunet
2
如果您有动态的"data-sort"属性,请将"data(“sort”)"替换为"attr(“data-sort”)"。效果很好! - dxlliv
1
@Michaela.Merz 老评论,但供参考:使用排序函数时,元素不会被复制,因此在使用appendTo时,它会将元素移动到它们已经存在的相同div中,从而实现原地排序。 - Gugu72

12

这个问题已经在这里回答过:

重新发布:

在许多解决方案中搜索后,我决定写一篇关于如何在jquery中进行排序的博客。总之,按数据属性对jquery "类数组"对象进行排序的步骤如下:

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

Html

<div class="item" data-order="2">2</div>
<div class="item" data-order="1">1</div>
<div class="item" data-order="4">4</div>
<div class="item" data-order="3">3</div>

纯jquery选择器

$('.item');
[<div class="item" data-order="1">1</div>,
 <div class="item" data-order="2">2</div>,
 <div class="item" data-order="3">3</div>,
 <div class="item" data-order="4">4</div>
]

按照data-order排序

function getSorted(selector, attrName) {
    return $($(selector).toArray().sort(function(a, b){
        var aVal = parseInt(a.getAttribute(attrName)),
            bVal = parseInt(b.getAttribute(attrName));
        return aVal - bVal;
    }));
}
> getSorted('.item', 'data-order')
[<div class="item" data-order="1">1</div>,
 <div class="item" data-order="2">2</div>,
 <div class="item" data-order="3">3</div>,
 <div class="item" data-order="4">4</div>
]

请查看getSorted()的工作方式。

希望这有所帮助!


1
我使用这个来对图库中的图片进行排序,其中排序数组将会被一个ajax调用所改变。希望对某些人有所帮助。

var myArray = ['2', '3', '1'];
var elArray = [];

$('.imgs').each(function() {
    elArray[$(this).data('image-id')] = $(this);
});

$.each(myArray,function(index,value){
   $('#container').append(elArray[value]); 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div id='container'>
   <div class="imgs" data-image-id='1'>1</div>
   <div class="imgs" data-image-id='2'>2</div>
   <div class="imgs" data-image-id='3'>3</div>
</div>

代码演示:http://jsfiddle.net/ruys9ksg/


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