首页 > 解决方案 > 使用 jquery 对嵌套列表进行排序

问题描述

我正在尝试对嵌套列表进行排序。我遇到了这个链接:Sorting <li> elements of a <Ul> based on text in <span> inside <li>

它让我大部分时间到达那里,但是,它假设你没有像这样的列表

<ul>
  <li><span>sortable text a</span>
    <ul>
      <li><span>sortable subtext</span></li>
    </ul>
  </li>
<ul>

每当我使用上面建议的代码时,任何嵌套列表都会附加到嵌套列表中的第一个<li>。我需要它转到原始列表项。

我的代码:

$(document).ready(function() {
  // for each ul separately
  $('#rootUl ul, ul').each(function(_, ul) {
    // get all the nodes to be sorted
    var $toSort = $(ul).children('li').children('span');

    // extract the text
    var values = $toSort.get().map(function(span) {
      return span.textContent;
    });

    // sort the text
    values.sort();

    // shove reordered texts back into the original elements
    values.forEach(function(value, index) {
      $toSort[index].textContent = value;
    });
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="rootUl">
  <li><span>zzz</span>
    <ul>
      <li><span>dd zzz</span></li>
      <li><span>aa zzz</span></li>
      <li><span>bb zzz</span></li>
    </ul>
  </li>
  <li><span>ccc</span>
    <ul>
      <li><span>ll ccc</span></li>
      <li><span>nn ccc</span></li>
      <li><span>mm ccc</span></li>
    </ul>
  </li>
  <li><span>rrr</span>
    <ul>
      <li><span>ss rrr</span>
        <ul>
          <li><span>dd ss rrr</span></li>
          <li><span>ff ss rrr</span></li>
          <li><span>ee ss rrr</span></li>
        </ul>
      </li>
      <li><span>rr rrr</span></li>
      <li><span>qq rrr</span></li>
    </ul>
  </li>
</ul>

我期望以下内容:

<ul id="rootUl">
  <li>
    <span>ccc</span>
    <ul>
      <li><span>ll ccc</span></li>
      <li><span>mm ccc</span></li>
      <li><span>nn ccc</span></li>
    </ul>
  </li>
  <li>
    <span>rrr</span>
    <ul>
      <li><span>qq rrr</span></li>
      <li><span>rr rrr</span></li>
      <li><span>ss rrr</span>
        <ul>
          <li><span>dd ss rrr</span></li>
          <li><span>ee ss rrr</span></li>
          <li><span>ff ss rrr</span></li>
        </ul>
      </li>
    </ul>
  </li>
  <li>
    <span>zzz</span>
    <ul>
      <li><span>aa zzz</span></li>
      <li><span>bb zzz</span></li>
      <li><span>dd zzz</span></li>
    </ul>
  </li>
</ul>

但相反,我得到了这个:

<ul id="rootUl">
  <li>
    <span>ccc</span>
    <ul>
      <li><span>aa zzz</span></li>
      <li><span>bb zzz</span></li>
      <li><span>dd zzz</span></li>
    </ul>
  </li>
  <li>
    <span>rrr</span>
    <ul>
      <li><span>ll ccc</span></li>
      <li><span>mm ccc</span></li>
      <li><span>nn ccc</span></li>
    </ul>
  </li>
  <li><span>zzz</span>
    <ul>
      <li>
        <span>qq rrr</span>
        <ul>
          <li><span>dd ss rrr</span></li>
          <li><span>ee ss rrr</span></li>
          <li><span>ff ss rrr</span></li>
        </ul>
      </li>
      <li><span>rr rrr</span></li>
      <li><span>ss rrr</span></li>
    </ul>
  </li>
</ul>

标签: jquerylistnested

解决方案


您需要对li其父列表中的元素进行排序,而不仅仅是移动spans 的文本内容。使用一个回调函数sort()来比较 span 的文本。

对 s 进行排序后li,您可以将它们附加到它们的父ul级以在 DOM 中重新排列它们。

也没有必要在选择器中同时指定#rootUl uland ul,因为ul会匹配#rootUl ul.

$(document).ready(function() {
  // for each ul separately
  $('ul').each(function(_, ul) {
    // get all the nodes to be sorted
    var $toSort = $(ul).children('li');
    $toSort.sort((li1, li2) => $(li1).children("span").text().localeCompare($(li2).children("span").text()));
    $toSort.each(function() {
      $(this).appendTo(ul);
    });
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="rootUl">
  <li><span>zzz</span>
    <ul>
      <li><span>dd zzz</span></li>
      <li><span>aa zzz</span></li>
      <li><span>bb zzz</span></li>
    </ul>
  </li>
  <li><span>ccc</span>
    <ul>
      <li><span>ll ccc</span></li>
      <li><span>nn ccc</span></li>
      <li><span>mm ccc</span></li>
    </ul>
  </li>
  <li><span>rrr</span>
    <ul>
      <li><span>ss rrr</span>
        <ul>
          <li><span>dd ss rrr</span></li>
          <li><span>ff ss rrr</span></li>
          <li><span>ee ss rrr</span></li>
        </ul>
      </li>
      <li><span>rr rrr</span></li>
      <li><span>qq rrr</span></li>
    </ul>
  </li>
</ul>


推荐阅读