基于数据属性值的jquery排序列表

时间:2014-02-06 10:52:59

标签: jquery

给出以下列表

<ul class="listitems">
    <li data-position="1">Item 1</li>
    <li data-position="2">Item 2</li>
    <li data-position="3">Item 3</li>
    <li data-position="4">Item 4</li>
</ul>

页面上有一些功能可以让这些项目改变位置。例如,他们可能会达到以下状态(仅限示例,订单可以是任何内容):

<ul class="listitems">
    <li data-position="3">Item 3</li>
    <li data-position="2">Item 2</li>
    <li data-position="1">Item 1</li>
    <li data-position="4">Item 4</li>
</ul>

我正在寻找一个小功能来重置订单。到目前为止,我有以下内容:

function setPositions()
{
    $( '.listitems li' ).each(function() {
        var position = $(this).data('position');
        $(this).siblings().eq(position+1).after(this);
    });
}

但它无法正常工作。我做错了什么?

附加条件是列表的顺序可能没有改变,因此该函数也必须在该场景中工作。

5 个答案:

答案 0 :(得分:97)

尝试将sort()appendTo()

一起使用
$(".listitems li").sort(sort_li) // sort elements
                  .appendTo('.listitems'); // append again to the list
// sort function callback
function sort_li(a, b){
    return ($(b).data('position')) < ($(a).data('position')) ? 1 : -1;    
}

<强>代码段,

$(function() {
  $(".listitems li").sort(sort_li).appendTo('.listitems');
  function sort_li(a, b) {
    return ($(b).data('position')) < ($(a).data('position')) ? 1 : -1;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul class="listitems">
  <li data-position="3">Item 3</li>
  <li data-position="2">Item 2</li>
  <li data-position="1">Item 1</li>
  <li data-position="4">Item 4</li>
</ul>

答案 1 :(得分:6)

扩展Rohan的答案,如果你想让它适用于多个列表而不只是一个,你可以使用以下内容:

HTML:

<ul class="listitems autosort">
    <li data-position="3">Item 3</li>
    <li data-position="2">Item 2</li>
    <li data-position="1">Item 1</li>
    <li data-position="4">Item 4</li>
</ul>

<ul class="listitems autosort">
    <li data-position="5">Item 5</li>
    <li data-position="6">Item 6</li>
    <li data-position="3">Item 3</li>
    <li data-position="4">Item 4</li>
</ul>

使用Javascript:

$(".listitems.autosort").each(function(){
    $(this).html($(this).children('li').sort(function(a, b){
        return ($(b).data('position')) < ($(a).data('position')) ? 1 : -1;
    }));
});

这将允许您添加任意数量的列表,并通过设置类自动排序对它们进行排序。

Live Example

答案 2 :(得分:3)

我的提议,完整的javascript,是:

document.addEventListener("DOMContentLoaded", function(e) {
  Array.prototype.slice.call(document.querySelectorAll('.listitems li')).sort(function(a, b) {
    return a.getAttribute('data-position').localeCompare(b.getAttribute('data-position'));
  }).forEach(function(currValue) {
    currValue.parentNode.appendChild(currValue);
  });
});
<ul class="listitems">
    <li data-position="3">Item 3</li>
    <li data-position="2">Item 2</li>
    <li data-position="1">Item 1</li>
    <li data-position="4">Item 4</li>
</ul>

答案 3 :(得分:0)

使用sort并在DOM内部进行替换怎么办

function sortLiElements(a,b) {
	return parseInt($(a).data('position')) -   parseInt($(b).data('position'));
}

$('.listitems').html($('.listitems li').sort(sortLiElements));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<ul class="listitems">
    <li data-position="3">Item 3</li>
    <li data-position="2">Item 2</li>
    <li data-position="1">Item 1</li>
    <li data-position="4">Item 4</li>
</ul>

答案 4 :(得分:0)

尝试一下

function sortList() {
  var list, i, switching, b, shouldSwitch;
  list = document.getElementById("id01");
  switching = true;
  /* Make a loop that will continue until
  no switching has been done: */
  while (switching) {
     
    // start by saying: no switching is done:
    switching = false;
    b = list.getElementsByTagName("LI");
    // Loop through all list-items:
    for (i = 0; i < (b.length - 1); i++) {
      // start by saying there should be no switching:
      shouldSwitch = false;
      /* check if the next item should
      switch place with the current item: */
     //alert(b[i].getAttribute("order"));
      if (b[i].getAttribute("order").toLowerCase() > b[i + 1].getAttribute("order").toLowerCase()) {
        /* if next item is alphabetically
        lower than current item, mark as a switch
        and break the loop: */
        shouldSwitch = true;
        break;
      }
    }
    if (shouldSwitch) {
      /* If a switch has been marked, make the switch
      and mark the switch as done: */
      b[i].parentNode.insertBefore(b[i + 1], b[i]);
      switching = true;       
    }
  }
}
 <button onclick="sortList()">Sort List</button>
 
 <ul id="id01">
    <li order="A" class="disname disheader">Pending</li>
    <li order="AA" class="disname">302-1 Energy Consumption</li>
    <li order="AA" class="disname">302-3 Energy Intensity</li>
    <li order="DD" class="disname">EN-31 Environmental Expenditure/Investment</li>
    <li order="DD" class="disname">103-2  Environmental Grievances</li>
    <li order="D" class="disname disheader">Deactive</li>                               
    <li order="BB" class="disname">305-4  Emission Intensity</li>                             
    <li order="BB" class="disname">306-2 Total Waste</li>
    <li order="BB" class="disname">307-1 Compliance</li>
    <li order="AA" class="disname">302-4 Energy/Electricity Reduction Initiative</li>
    <li order="AA" class="disname">303-1 Water Withdrawal by Source</li>
    <li order="AA" class="disname">303-3 Recycled Water</li>
    <li order="C" class="disname disheader">Auto Generated</li>
    <li order="CC" class="disname">305-1 GHG Emission</li>
    <li order="CC" class="disname">305-2 GHG Emission</li>
    <li order="CC" class="disname">305-3 GHG Emission</li>
    <li order="BB" class="disname">05-5 Reduction of GHG Emissions</li>
    <li order="BB" class="disname">306-1 Water Discharge</li>  
    <li order="B" class="disname disheader">Overdue</li>                              
</ul>

Codepen Example