Sorting a list by data-attribute

后端 未结 3 1422
借酒劲吻你
借酒劲吻你 2020-12-20 02:16

I have a list of people with job titles sorted by the persons’ first names, like this:

相关标签:
3条回答
  • 2020-12-20 02:41

    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>.

    0 讨论(0)
  • 2020-12-20 02:48

    This works for any number of lists: it basically gathers all lis in uls that have your attribute, sorts them according to their data-* attribute value and re-appends them to their parent.

    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 lis in the same array, sorts them all, but in the end figures out which list the li originally belonged to. It’s a pretty simple and straight-forward solution.


    A slightly longer ECMAScript 5.1 alternative would be:

    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);
    });
    
    0 讨论(0)
  • 2020-12-20 03:01

    You can pass a comparison function to 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);
    
    0 讨论(0)
提交回复
热议问题