【问题标题】:Sort list itmes according to child element value根据子元素值对列表项进行排序
【发布时间】:2020-03-10 13:33:26
【问题描述】:

li 标签不止一个。在这些li 标签内有一个span 元素,其值为一个月。我想要的是使用li 标签内span 元素的month 文本值对li 标签进行排序。

例如;如果有li 标记并且在li 标记内有一个spanDecember 作为它的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 来实现这一点,但我没有 logix。欢迎询问更多详情。

【问题讨论】:

    标签: javascript html sorting date logic


    【解决方案1】:

    一种方法是使用实​​际日期和Date() 构造函数。通过这种方式,您可以相互评估确切的日期并在排序函数中使用它们。您已经有了月份,但在这种情况下,年份也是建立有效日期所必需的。最低要求是一年。在这种情况下,我们需要年和月。

    我使用了 HTML5 &lt;time&gt; 元素,它使您的日期更具语义。它有一个datetime 属性,屏幕阅读器和搜索引擎可以读取该属性以了解日期,例如NOV 是。我们可以使用datetime 属性中的值通过Date() 构造函数创建一个新日期。

    首先选择所有&lt;time&gt; 元素并使用Array.from() 或扩展语法[...elements]querySelectorAll 结果创建一个数组。这是使用所有数组中都可用的sort 方法所必需的。

    sort() 方法中,将datetime 属性中的值相互比较以创建订单。现在已经设置了顺序,我们要将其应用于文档。再次循环日期,并使用 Flexbox 的 order 属性根据已排序数组的索引设置正确的顺序。

    您还需要在&lt;ul&gt; 元素上添加display: flex;flex-direction: column,以使&lt;li&gt; 元素与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>

    【讨论】:

    • 对不受支持的时间戳格式使用内置解析器不是一个好主意。日期将使用 * datetime* 属性按词法排序,不需要 Date 对象。
    • 您说得对。使用日期简单的字符串也可以解决问题。我会进行编辑。
    • 请不要叫我“先生”,在我的文化中,这不是恭维。 :-)
    • 我很抱歉。我没有不尊重的意思,罗伯。如果我可以问的话,你的文化是什么?
    【解决方案2】:

    试试:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多