Сортировка элементов li без разрушения подсписка

Мне очень нужна помощь в сортировке. Я хотел бы отсортировать список как:

  • банан
  • торт
    • яйцо
    • пончик
    • бутерброд
  • рис
  • яблоко

и превратиться в:

  • яблоко
  • банан
  • торт
    • яйцо
    • пончик
    • бутерброд
  • рис
<html>
    <head>
        <title>Sort list items alphabetically with Javascript</title>
        <script type="text/javascript">

        function sortUnorderedList(ul, sortDescending) {
          if(typeof ul == "string")
            ul = document.getElementById(ul);

          var lis = ul.getElementsByTagName("LI");
          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;
          document.getElementById("test").onclick = function() {
            sortUnorderedList("list", desc);
            desc = !desc;
            return false;
          }
        }

        </script>
    </head>
    <body>
        <input type="button" id="test" value="Sort List (click again to reverse)"/>
        <ul id="list">
            <li>banana</li>
            <li>cake</li>
              <ul>
                <li>egg</li>
                <li>doughnut</li>
                <li>burger</li>
              </ul>
            <li>rice</li>
            <li>apple</li>
        </ul>
    </body>
</html>

Я бы очень признателен за любую помощь. Спасибо и храни вас Бог!

Всего 1 ответ


Основная проблема с вашим кодом заключается в том, что ваш HTML-код недействителен; ul не может быть ребенком другого ul . Только li или ol может. Этот недопустимый HTML-код приводит к тому, что li будет отображаться не так, как вы ожидаете, поэтому на сортировку влияет. Чтобы исправить это, исправьте HTML, чтобы вложенный «торт» ul находился в пределах li .

Поскольку вы пометили вопрос с помощью jQuery, вот очень простая реализация того, что у вас изначально было:

jQuery($ => {
  let $ul = $('#list');

  $('#test').on('click', function() {
    let sort = $(this).data('sortasc');
    let dir = sort ? [1, -1] : [-1, 1];
    $ul.children('li').sort((a, b) => a.innerText.trim() < b.innerText.trim() ? dir[0] : dir[1]).appendTo($ul);
    $(this).data('sortasc', !sort);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="test">Toggle sort</button>
<ul id="list">
  <li>banana</li>
  <li>
    cake
    <ul>
      <li>egg</li>
      <li>doughnut</li>
      <li>burger</li>
    </ul>
  </li>
  <li>rice</li>
  <li>apple</li>
</ul>


Есть идеи?

10000