仅在第一级对带有嵌套列表的未排序列表(li)进行排序

时间:2020-05-15 07:47:13

标签: javascript jquery

我要列出以下列表:

function sortUnorderedList(ul, sortDescending) {
  if (typeof ul == "string")
  var lis = $( "li", ".text-error" );
  var vals = [];
  for (var i = 0, l = lis.length; i < l; i++)
    vals.push(lis[i].innerHTML);
  vals.sort();
  if (sortDescending)
    vals.reverse();
  for (var i = 0, l = lis.length; i < l; i++)
    lis[i].innerHTML = vals[i];
}
window.onload = function() {
  var desc = false;
  sortUnorderedList("list", desc);
  desc = !desc;
  return false;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="text-error">
   <li>Brush your teeth</li>
   <li>Wash your hands</li>
   <li>Do your homework</li>
   <li>Do not use curse-words</li>
   <li id="files-errorPrincipals">Act polite:
       <ul class="text-error">
          <li class="file-error">Say Hello</li>
          <li class="file-error">Say Goodbye</li>
       </ul>
   </li>
   <li id="files-error">Always remember:
       <ul id="files-error-list" class="text-error">
          <li class="file-error">Think for yourself</li>
          <li class="file-error">Think twice</li>
       </ul>
   </li>
</ul>

这适用于第一级列表项,但未对具有嵌套列表的列表项进行排序。

如何对所有第一级列表项进行排序?

3 个答案:

答案 0 :(得分:2)

我认为首先隔离每个上下文(在您的情况下似乎是.text-error)然后再逐一遍历它们会更容易。 此示例将在各自的级别上迭代嵌套的li

function sortUnorderedList(ul, sortDescending) {
  if (typeof ul == "string") {
    //Get each individual ul/li-context to sort inside
    var contexts = $('.text-error');
    
    //Iterarate over individual contexts
    contexts.each(function(i,ctx){
        //Get first level <li> elements in specific context
        var lis = $(ctx).children('li');

        //Sort the results
        lis.sort(function(a, b){
          var sortResult = $(a).text().localeCompare($(b).text());
          if(sortDescending){ sortResult = 0 - sortResult }
          return sortResult;
        });

        //Append the items
        lis.each(function(i2, li){
            ctx.append(li);
        })
    }) 
  }
}

window.onload = function() {
  var desc = false;
  sortUnorderedList("list", desc);
  desc = !desc;
  return false;
}
/*CSS for exampe rendering clarity*/
ul{
  font-size: 0.85em;
  font-family: sans-serif;
  list-style-type: none;
  line-height: calc(1em + 2px);
}
li > ul{
  border-top:1px solid gainsboro;
}
li {
  border-left: 1px solid gray;
  width: 0;
  white-space: nowrap;
  padding: 1px;
}
  li li, li ul {
    border-color: silver;
    color:dimgray;
  }
    li li li, li li ul {
      border-color: gainsboro;
      color:gray;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="text-error">
   <li>Brush your teeth</li>
   <li>Wash your hands</li>
   <li>Do your homework</li>
   <li>Do not use curse-words</li>
   <li id="files-errorPrincipals">Act polite:
       <ul class="text-error">
          <li class="file-error">Say Hello</li>
          <li class="file-error">Say Goodbye</li>
       </ul>
   </li>
   <li id="files-error">Always remember:
       <ul id="files-error-list" class="text-error">
          <li class="file-error">Think for yourself</li>
          <li class="file-error">Think twice</li>
       </ul>
   </li>
</ul>

<h3>Bolow is an example illustrating the sorting on single individual levels.</h3>
<ul class="text-error">
   <li>C</li>
   <li>F</li>
   <li>A</li>
   <li>G</li>
   <li>B</li>
   <li>D
   <ul class="text-error">
          <li>D3</li>
          <li>D1</li>
          <li>D2
            <ul class="text-error">
              <li>D2-1</li>
              <li>D2-3</li>
              <li>D2-2</li>
              <li>D2-4</li>
            </ul>
          </li>
          <li>D5</li>
          <li>D4</li>
       </ul>
   </li>
   <li>E
   <ul class="text-error">
          <li>E1</li>
          <li>E3</li>
          <li>E4</li>
          <li>E2</li>
          <li>E5
            <ul class="text-error">
              <li>E5-1</li>
              <li>E5-4</li>
              <li>E5-2</li>
              <li>E5-3</li>
            </ul>
          </li>
       </ul>
   </li>
</ul>

答案 1 :(得分:1)

您可以创建递归函数,该函数将在ul内查找li个元素,如果存在,它将对每个嵌套的ul进行排序。

function sortHTML(el) {
  const li = el.find('> li');

  const sorted = li.sort((a, b) => {
    return $(a).text().localeCompare($(b).text())
  })

  li.each(function() {
    const ul = $(this).find('ul');
    if (ul.length) {
      ul.each(function() {
        sortHTML($(this))
      })
    }
  })

  el.html(sorted)
}

sortHTML($('body > ul.text-error'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="text-error">
  <li>Brush your teeth</li>
  <li>Wash your hands</li>
  <li>Do your homework</li>
  <li>Do not use curse-words</li>
  <li id="files-errorPrincipals">Act polite:
    <ul class="text-error">
      <li class="file-error">Say Hello</li>
      <li class="file-error">Say Goodbye</li>
    </ul>
  </li>
  <li id="files-error">Always remember:
    <ul id="files-error-list" class="text-error">
      <li class="file-error">Think for yourself</li>
      <li class="file-error">Think twice</li>
    </ul>
  </li>
</ul>

答案 2 :(得分:1)

您要递归地浏览树。

为此,您可以进行深度优先或广度优先的搜索,但是为什么事情过于复杂呢? jQuery具有内置的递归“查找所有内容”功能!

已更新:使用原始的排序功能。为什么不!并添加了一个简化的代码版本。

我正在使用一个简单的过滤器仅对.sort个项目进行排序,因此它不会占据整个页面。

function sortItems(parent, childSelector) {
  var items = parent.children(childSelector).sort(function(a, b) {
    return $(a).text().localeCompare($(b).text())
  });
  parent.append(items);
}

$().ready(function () {
  // ".sort" filter to limit what it sorts, could be "ul" instead
  $('body').find(".sort").each(function () {
    sortItems($(this), "li");
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="sort">
 <li>Brush your teeth</li>
 <li>Wash your hands</li>
 <li>Do your homework</li>
 <li>Do not use curse-words</li>
 <li>Act polite:
    <ul class="sort">
       <li>Say Hello</li>
       <li>Say Goodbye</li>
    </ul>
 </li>
 <li>Always remember:
    <ul class="sort">
      <li>Think for yourself</li>
      <li>Think twice</li>
    </ul>
 </li>
</ul>

更小的版本:

$().ready(function () {
  // ".sort" filter to limit what it sorts, could be "ul" instead
  // This is jQuery's recursive search function - "find(<filter>)".
  $('body').find(".sort").each(function () {
        // For each item we want to sort ("find().each()"), sort them.
        // Note: I'm explicitly filtering for "li" items to sort.
        var sortedChildren = $(this).children("li").sort(function(a, b) {
          return $(a).text().localeCompare($(b).text());
        });
        $(this).append(sortedChildren);
  });
});
相关问题