简体   繁体   English

按数据属性对列表进行排序

[英]Sorting a list by data-attribute

I have a list of people with job titles sorted by the persons' first names, like this:我有一个按人名排序的职位列表,如下所示:

<ul>
  <li data-azsort="smithjohn">
    <a href="#">
      <span class="list-name">John Smith</span>
    </a>
    <span class="list-desc">Professor</span>
  </li>
  ..
  <li data-azsort="barnestom">
    <a href="#">
      <span class="list-name">Tom Barnes</span>
    </a>
    <span class="list-desc">Lecturer</span>
  </li>
</ul>

I've added the data-azsort attribute to the <li> element, and I'd like to pop these list elements into an array, and sort based on that data-* attribute (using plain JavaScript).我已将data-azsort属性添加到<li>元素,并且我想将这些列表元素弹出到一个数组中,并根据该data-*属性进行排序(使用纯 JavaScript)。

What would be the best way to sort the list by data-azsort (AZ), returning the same code?通过data-azsort (AZ) 对列表进行排序并返回相同代码的最佳方法是什么? JavaScript only, no jQuery, etc.只有 JavaScript,没有 jQuery 等。

This works for any number of lists: it basically gathers all li s in ul s that have your attribute, sorts them according to their data-* attribute value and re-appends them to their parent.这适用于任意数量的列表:它基本上收集ul中具有您的属性的所有li ,根据它们的data-*属性值对它们进行排序,并将它们重新附加到它们的父级。

 Array.from(document.querySelectorAll("ul > li[data-azsort]")) .sort(({dataset: {azsort: a}}, {dataset: {azsort: b}}) => a.localeCompare(b)) // To reverse it, use `b.localeCompare(a)`. .forEach((item) => item.parentNode.appendChild(item));
 <ul> <li data-azsort="skeetjon"> <a href="#"><span class="list-name">Jon Skeet</span></a> <span class="list-desc">Stack Overflow user</span> </li> <li data-azsort="smithjohn"> <a href="#"><span class="list-name">John Smith</span></a> <span class="list-desc">Professor</span> </li> <li data-azsort="barnestom"> <a href="#"><span class="list-name">Tom Barnes</span></a> <span class="list-desc">Lecturer</span> </li> </ul> <ul> <li data-azsort="smithjohn"> <a href="#"><span class="list-name">John Smith</span></a> <span class="list-desc">Professor</span> </li> <li data-azsort="barnestom"> <a href="#"><span class="list-name">Tom Barnes</span></a> <span class="list-desc">Lecturer</span> </li> <li data-azsort="skeetjon"> <a href="#"><span class="list-name">Jon Skeet</span></a> <span class="list-desc">Stack Overflow user</span> </li> </ul>

The funny thing is, it gets all li s in the same array, sorts them all, but in the end figures out which list the li originally belonged to.有趣的是,它获取同一个数组中的所有li ,对它们进行排序,但最终找出li最初属于哪个列表。 It's a pretty simple and straight-forward solution.这是一个非常简单直接的解决方案。

If you want to sort elements by a numeric data attribute, then use this sort function instead:如果要按数字数据属性对元素进行排序,请改用此排序函数:

// Presumably, the data-* attribute won’t be called `azsort`. Let’s call it `numsort`.
({dataset: {numsort: a}}, {dataset: {numsort: b}}) => Number(a) - Number(b) // `Number(b) - Number(a)` to reverse the sort.

A slightly longer ECMAScript 5.1 alternative would be:一个稍长的 ECMAScript 5.1 替代方案是:

Array.prototype.slice.call(document.querySelectorAll("ul > li[data-azsort]")).sort(function(a, b) {
  a = a.getAttribute("data-azsort");
  b = b.getAttribute("data-azsort");

  return a.localeCompare(b);
}).forEach(function(node) {
  node.parentNode.appendChild(node);
});

What about getting all of the list items, push them into array which later will be sorted?获取所有列表项,将它们推送到稍后将被排序的数组中怎么样?

 var allListElements = document.getElementById("staff").getElementsByTagName("li"); var staff = new Array(); for (i = 0; i < allListElements.length; i++) { staff.push(allListElements[i].getAttribute('data-azsort')); } staff.sort(function(a, b) { if (a < b) return -1; if (a > b) return 1; return 0; }); //Print document.write('<h4>Sorted</h4>'); for (i = 0; i < staff.length; i++) { document.write(staff[i] + "<br />"); }
 <h4>Input</h4> <ul id="staff"> <li data-azsort="smithjohn"> <a href="#"> <span class="list-name">John Smith</span> </a> <span class="list-desc">Professor</span> </li> <li data-azsort="barnestom"> <a href="#"> <span class="list-name">Tom Barnes</span> </a> <span class="list-desc">Lecturer</span> </li> </ul>

Additionally you can save the index of <li> and reorder the <ul> .此外,您可以保存<li>的索引并重新排序<ul>

You can pass a comparison function to Array.prototype.sort您可以将比较函数传递给 Array.prototype.sort

you should be able to do something like你应该能够做类似的事情

$items = $('li[data-azsort]');
var compareElem = function (a, b) {
  if (a.attr('data-azsort') > b.attr('data-azsort') {
    return 1;
  } else {
   return -1
  }
};
Array.prototype.sort.apply($items, compareElem);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM