根据孩子的HTML

时间:2018-02-20 23:56:51

标签: javascript html mysql sorting

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

情况

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

#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"和{{1}的内容元素将是相同的。

目标

我希望能够根据class="hashtag-pop"(AZ和ZA)的值按字母顺序对网格中的数据进行排序和重新排序,并根据class="channel"和{的值进行数字排序和重新排序{1}}(0-1和1-0)。但是,我对于如何做到这一点有一个大脑放屁。

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

方法

由于class="channel-pop"class="hashtag-pop"中的数据并不总是唯一的,我知道我需要将子元素或其内容映射到父C1,我可以使用C3属性,JS中的对象,地图对象等

我并不完全熟悉地图对象,所以目前,当页面加载时,我将container属性添加到父容器中,如下所示:

data-

然而,当然,当我遍历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的值再次与父元素解除关联。 / p>



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

1 个答案:

答案 0 :(得分:1)

  

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

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

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数组进行排序。在使用排序的gridRows数组中的DOM对象引用值替换DOM中的容器对象时,您不需要首先将其删除 - 在这种情况下追加(对于同一父项)将移动现有DOM反对而不是复制它。

<小时/> 一个工作示例

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

通过按排序顺序将container项添加到#table元素来完成更新显示。它保留使用<text>元素但不使用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>