Сортировать список элементов по значению дочернего элемента - PullRequest
0 голосов
/ 10 марта 2020

Существует более одного li тега. Внутри этих тегов li есть элемент span, который имеет значение месяца. Я хочу отсортировать теги li, используя текстовое значение month элемента span внутри тега li.

Например; Если есть тег li и внутри тега li есть span с December в качестве innerHTML, этот тег li должен находиться внизу списка, поскольку December является последним месяц года.

Ниже приведен код html.

<ul class="timeline-items">
                <h2 class="fables-second-background-color date-circle">2018</h2>
                <li class="is-hidden timeline-item">
                    <span class="gallery-mlti-date">MAY</span>
                </li>
                <li class="is-hidden timeline-item">
                    <span class="gallery-mlti-date">NOV</span>
                </li>
                <li class="is-hidden timeline-item">
                    <span class="gallery-mlti-date">SEP</span>
                </li>
                <li class="is-hidden timeline-item">
                    <span class="gallery-mlti-date">NOV</span>
                </li>
            </ul>

      <script>
      const months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
     </script>

Я пробовал много подходов для достижения этой цели, используя javascript, но мой я вне логикса. Не стесняйтесь спрашивать более подробную информацию.

Ответы [ 2 ]

1 голос
/ 10 марта 2020

попробуй:

<h2 class="fables-second-background-color date-circle">2018</h2>
  
  <ul class="js-timeline-list timeline-items">
      <li class="is-hidden timeline-item">
          <span class="gallery-mlti-date">MAY</span>
      </li>
      <li class="is-hidden timeline-item">
          <span class="gallery-mlti-date">NOV</span>
      </li>
      <li class="is-hidden timeline-item">
          <span class="gallery-mlti-date">SEP</span>
      </li>
      <li class="is-hidden timeline-item">
          <span class="gallery-mlti-date">NOV</span>
      </li>
  </ul>

  <script>
    function sortList(list) {
        let i = 0;
        const months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
        const children = list.children;
      
        for (i = 1; i < children.length; i++) {
            for (let j = i; j > 0; j--) {
                let leftChild = children[j].children[0].innerHTML;
                let rightChild = children[j - 1].children[0].innerHTML;

                if (months.indexOf(leftChild) >= months.indexOf(rightChild)) continue;
                children[j].parentNode.insertBefore(children[j], children[j - 1]);
            }
        }
        
    }
  
    const root = document.querySelector('.js-timeline-list');
    sortList(root)
  </script>
1 голос
/ 10 марта 2020

Один из способов сделать это - использовать фактические даты и конструктор Date(). Таким образом, вы можете оценить точные даты друг с другом и использовать их в функции сортировки. У вас уже есть месяц, но в этом случае год также необходим для построения правильной даты. Минимальное требование - год. В этом случае нам нужны и год, и месяц.

Я использовал элемент HTML5 <time>, который делает вашу дату более семантичной c. Он имеет атрибут datetime, который программы чтения с экрана и поисковые системы могут прочитать, чтобы узнать, какая дата, например, NOV. Мы можем использовать значение в атрибуте datetime для создания новой даты с помощью конструктора Date().

Сначала выберите все элементы <time> и используйте Array.from() или синтаксис расширения [...elements] для создания массива из результата querySelectorAll. Это необходимо для использования метода sort, который доступен во всех массивах.

В методе sort() сравните значения атрибута datetime друг с другом, чтобы создать приказ. Теперь порядок установлен, мы хотим применить его к документу. L oop через даты снова и используйте свойство order Flexbox, чтобы установить правильный порядок на основе индекса отсортированного массива.

Вам также нужно будет добавить display: flex; и flex-direction: column на вашем <ul> элементе, чтобы заставить <li> элементы работать со свойством order.

Дайте мне знать, если я не был ясен или у вас есть еще вопросы.

// Get the <time> elements and put them in an array.
const dates = Array.from(document.querySelectorAll('.gallery-mlti-date'));

// Sort by date. From January to December.
dates.sort((a, b) => new Date(a.dateTime) - new Date(b.dateTime));

// Set order of list items by index of sorted list.
dates.forEach((date, index) => date.parentElement.style.order = index);
.timeline-items {
  display: flex;
  flex-direction: column;
}
<h2 class="fables-second-background-color date-circle">2018</h2>
<ul class="timeline-items">
  <li class="is-hidden timeline-item">
    <time datetime="2020-05" class="gallery-mlti-date">MAY</time>
  </li>
  <li class="is-hidden timeline-item">
    <time datetime="2020-11" class="gallery-mlti-date">NOV</time>
  </li>
  <li class="is-hidden timeline-item">
    <time datetime="2020-09" class="gallery-mlti-date">SEP</time>
  </li>
  <li class="is-hidden timeline-item">
    <time datetime="2020-11" class="gallery-mlti-date">NOV</time>
  </li>
</ul>
...