【问题标题】:Sorting parent elements based on children's HTML根据子级 HTML 对父级元素进行排序
【发布时间】:2018-07-31 10:58:57
【问题描述】:

我已经有一段时间没有编码了,所以我现在有点不知所措。

情况

我正在我的网站上使用数据库中的数据填充一个表(或者更确切地说是一个网格)。下面是代码的结构:

#table {
  display: grid;
}
<div id="table">
  <div class="container" id="1340firstitem">
    <text class="channel-pop">  100,022         </text>
    <text class="channel"    >  @1340firstitem  </text>
    <text class="hashtag-pop">  1,100           </text>
  </div>
  <div class="container" id="second_item">
    <text class="channel-pop">  555             </text>
    <text class="channel"    >  @second_item    </text>
    <text class="hashtag-pop">  49              </text>
  </div>
  <div class="container" id="3rd.item">
    <text class="channel-pop">  100,022        </text>
    <text class="channel"    >  @3rd.item      </text>
    <text class="hashtag-pop">  49             </text>
  </div>
</div>

信息在页面上的显示方式如下:

______C1____|________C2________|____C3______
   100,022  |  @1340firstitem  |  1,100
       555  |  @second_item    |     49
   100,022  |  @3rd.item       |     49

C2class="channel" 元素的内容总是唯一,有时class="channel-pop"class="hashtag-pop" 元素的内容将是相同的。

目标

我希望能够根据class="channel"(AZ 和 ZA)的值按字母顺序对网格中的数据进行排序和重新排序,并根据class="channel-pop"class="hashtag-pop"(0 -1 和 1-0)。但是,我对如何去做这件事感到头疼。

最终数据库会变得非常密集,因此我需要尽可能高效地执行此操作——不要循环遍历嵌套数组或在循环内循环内使用循环...

方法

由于C1C3 中的数据并不总是唯一的,我知道我需要将子元素或其内容映射到父container,这可以使用data- 属性来完成,对象JS中,地图对象等

我对地图对象并不完全熟悉,所以目前,当页面加载时,我正在向父容器添加data- 属性,如下所示:

  <div class="container" id="1340firstitem"
    data-channel-pop="100,022"
    data-hashtag-pop="1,100"
  >
    <text class="channel-pop">  100,022         </text>
    <text class="channel"    >  @1340firstitem  </text>
    <text class="hashtag-pop">  1,100           </text>
  </div>

当然,当我遍历container 类并创建这些data- 属性的数组时,data- 的值再次与父元素解除关联。



我有一段时间没有编码了,所以我现在正努力解决这个问题。任何帮助将不胜感激。

【问题讨论】:

  • 有无数种方法可以做到这一点,而且您似乎没有遇到任何问题,因为您还没有做到那么远。我认为您需要的是教程,而不是问答。
  • @powerbuoy 其实按照HTML5规范,你可以自己创建元素。例如:developer.mozilla.org/en-US/docs/Web/Web_Components/…
  • @Anthony 我创建了一支可以进行简单排序的笔。它没有正确排序数字。也许这是一个开始。 codepen.io/Rechousa/pen/vdjELr
  • 已更新,抱歉,我忘记链接了 :)
  • Pen codepen.io/Rechousa/pen/vdjELr 更新为纯 JavaScript。希望对您有所帮助。

标签: javascript html mysql sorting


【解决方案1】:

当然,当我遍历容器类并创建这些 data- 属性的数组时, data- 的值再次与父元素解除关联。

这看起来像是设计错误。创建一个可排序的容器对象数据数组,比如:

const gridRows = Array.from(
                    document.getElementById("table")
                    .querySelectorAll(".container")
                 ).map ( container => [
                             container,
                             container.children[0].textContent.trim(),
                             container.children[1].textContent.trim(),
                             container.children[2].textContent.trim()
                         ]
                 );

这只是一个示例*,它创建了一个内部数组的数组,格式为

 [ containerDOMobject, columnOneText, columnTwoText, columnThreeText]

(*映射函数可以优化以避免创建三个子节点列表,为简单起见,映射元素以数组形式呈现。)

以任何需要的方式对gridRows 数组进行排序。替换 DOM 中的容器对象时,使用排序后的 gridRows 数组中的 DOM 对象引用值,您无需先将其删除 - 追加(在本例中为同一个父对象)将移动现有的 DOM 对象而不是而不是复制它。


一个有效的例子

gridRows 准备的变体可以将数字条目转换为数字以进行排序。首先创建gridRows 的原因是为了简化和加快排序 - 正如一位评论员所指出的,有多种方法可以实现您的目标。

通过将container 项目按排序顺序附加到#table 元素来更新显示。它保留使用 &lt;text&gt; 元素但不使用 display:grid 布局。如何对display:grid 元素的内容进行排序值得单独提出一个问题。

document.addEventListener("DOMContentLoaded", function(event) {

    let ascending = 1;
    let sortColumn = undefined;
    let uniqueColumn = document.getElementById("channelColumn").dataset.value;

    const gridRows = Array.from(
            document.getElementById("table")
            .querySelectorAll(".container")
        ).map ( container =>
        {
            const children = container.children;
            let data = [
                container,
                children[0].textContent.trim(),
                children[1].textContent.trim(),
                children[2].textContent.trim()
            ];
            for( var i of [1,3]) {
                data[i] = Number( data[i].replace(",", ""));
            }
            return data;
        });

    function compareRows( aRow, bRow) {
        let a = aRow[sortColumn];
        let b = bRow[sortColumn];
        if( a > b) {
            return ascending;
        }
        if( a < b) {
            return -ascending;
        }
        a = aRow[uniqueColumn];
        b = bRow[uniqueColumn];
        if( a > b) {
            return ascending;
        }
        if( a < b) {
            return -ascending;
        }
        return 0;
    }

    function sortGrid( event) {
        let target = event.target;
        let column = target.dataset.column;
        let table = document.getElementById("table");
        
        if( column) {
            ascending = column === sortColumn ? -ascending : 1;
            sortColumn = column;
            gridRows.sort( compareRows);
            gridRows.forEach( data => table.appendChild(data[0]));
        }
    }

    document.getElementById("sortBy").addEventListener("click", sortGrid);
});
#table: {
}
#sortBy {
   font-weight: bold;
   color: teal;
   border-bottom: medium solid grey;
   cursor: default;
}
text {
   display: inline-block;
   width: 30%;
   text-align: right;
}
<div id="table">
  <div id="sortBy"><!-- table header -->
<text data-column="1">channel-pop</text>
<text id="channelColumn" data-column="2">channel</text>
<text data-column="3">hashtag-pop</text>
  </div>

  <div class="container" id="1340firstitem">
<text class="channel-pop">  100,022         </text>
<text class="channel"    >  @1340firstitem  </text>
<text class="hashtag-pop">  1,100           </text>
  </div>
  <div class="container" id="second_item">
<text class="channel-pop">  555             </text>
<text class="channel"    >  @second_item    </text>
<text class="hashtag-pop">  49              </text>
  </div>
  <div class="container" id="3rd.item">
<text class="channel-pop">  100,022        </text>
<text class="channel"    >  @3rd.item      </text>
<text class="hashtag-pop">  49             </text>
  </div>
</div>

【讨论】:

  • 正如我在问题中所说,我真的不太了解地图对象,尽管我有直觉认为地图对象可能是最好的路线。我必须阅读更多关于它们的信息。
  • MapMap constructor 创建的对象与map method of Array objects 完全不同。我使用了后者——它所做的只是使用用户提供的转换函数将一个数组转换为另一个数组,而无需编写 for 循环 :)
猜你喜欢
  • 2013-07-23
  • 2016-03-02
  • 1970-01-01
  • 1970-01-01
  • 2019-01-22
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
相关资源
最近更新 更多