我想根据子值(span内容)对JavaScript div进行排序。
我在这里找到了一个关于javascript的排序算法: Easiest way to sort DOM nodes?
然而,这仅适用于简单列表。我希望有一个修改版本,不看段落元素。
HTML
<div class="myclass">
<p class="hide">1</p>
<span>2</span>
</div>
<div class="myclass">
<p class="hide">2</p>
<span>1</span>
</div>
<div class="myclass">
<p class="hide">3</p>
<span>4</span>
</div>
<div class="myclass">
<p class="hide">4</p>
<span>1</span>
</div>
JS
var list = document.getElementById('sortme');
var items = list.childNodes;
var itemsArr = [];
for (var i in items) {
// HERE I need to get to the SPAN Element but how?
if (items[i].nodeType == 1) { // get rid of the whitespace text nodes
itemsArr.push(items[i]);
}
}
itemsArr.sort(function(a, b) {
return a.innerHTML == b.innerHTML
? 0
: (a.innerHTML > b.innerHTML ? 1 : -1);
});
for (i = 0; i < itemsArr.length; ++i) {
list.appendChild(itemsArr[i]);
}
这是JSFiddle。
答案 0 :(得分:2)
这是一种可能的方法(demo):
var list = document.getElementById('sortme');
var nodesToSort = list.querySelectorAll('.myclass');
Array.prototype.map.call(nodesToSort, function(node) {
return {
node: node,
relevantText: node.querySelector('span').textContent
};
}).sort(function(a, b) {
return a.relevantText.localeCompare(b.relevantText);
}).forEach(function(item) {
list.appendChild(item.node);
});
正如您所注意到的,这里有一些变化。
首先,正如我所说,您不需要使用root.childNodes
,因为所有应该排序的项目都可以使用querySelectorAll
或getElementsByClassname
方法轻松收集(我选择前者,主要是出于一致性原因)。这也使基于nodeType
的过滤变得多余。
(实际上,如果作者使用children
属性代替childNodes
,那么链接答案中也会多余,
其次,排序辅助数组现在不仅包含节点,还包含对象;此技术的目的 - 也称为memoization - 是为了最大限度地减少DOM查询的数量,从而提高性能。
(此处我已将innerHTML
查询替换为textContent
,因为您似乎只对此处的文字感兴趣,忽略了<span>
中的任何内联标记。如果不是这种情况,只需将其替换回来)
最后,与原版的另一个变化:用简单的字符串函数替换双重比较(第一个==
,然后是>
) - localeCompare,专门用于比较字符串。
当然,现在整个过程的结构都是一系列操作:
......不需要任何中间变量和东西。
目前尚不清楚结构是否统一(即,您是否总是希望根据<span>
内容进行排序)。如果您只想根据可见文本进行排序,请考虑使用node.innerText
代替node.querySelector('span').textContent
。但请注意:innerText
,虽然现代浏览器支持,但根据定义,它是一个缓慢的计算值。
答案 1 :(得分:0)
您可以使用flexboxes和CSS order:属性来更改其显示顺序,而不是更改文档顺序。