如果我有这样的清单:
<ul id="mylist">
<li id="list-item1">text 1</li>
<li id="list-item2">text 2</li>
<li id="list-item3">text 3</li>
<li id="list-item4">text 4</li>
</ul>
根据我的偏好重新安排DOM节点的最简单方法是什么? (这需要在页面加载时自动发生,列表顺序首选项从cookie获得)
E.g。
<ul id="mylist">
<li id="list-item3">text 3</li>
<li id="list-item4">text 4</li>
<li id="list-item2">text 2</li>
<li id="list-item1">text 1</li>
</ul>
答案 0 :(得分:70)
虽然使用JS库可能有一种更简单的方法,但这是一个使用vanilla js的工作解决方案。
var list = document.getElementById('mylist');
var items = list.childNodes;
var itemsArr = [];
for (var i in items) {
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]);
}
答案 1 :(得分:15)
您可能会发现对DOM节点进行排序效果不佳。一种不同的方法是在你的javascript中有一个数组,它表示将进入DOM节点的数据,对数据进行排序,然后重新生成保存DOM节点的div。
也许你没有那么多节点要排序,所以没关系。我的经验是基于尝试通过操纵DOM来对HTML表进行排序,包括包含数百行和几十列的表。
答案 2 :(得分:13)
查看实际操作:http://jsfiddle.net/stefek99/y7JyT/
jQuery.fn.sortDomElements = (function() {
return function(comparator) {
return Array.prototype.sort.call(this, comparator).each(function(i) {
this.parentNode.appendChild(this);
});
};
})();
<强>简洁强>
答案 3 :(得分:9)
我的版本,希望对其他人有用:
var p = document.getElementById('mylist');
Array.prototype.slice.call(p.children)
.map(function (x) { return p.removeChild(x); })
.sort(function (x, y) { return /* your sort logic, compare x and y here */; })
.forEach(function (x) { p.appendChild(x); });
答案 4 :(得分:8)
如果您已经在使用jQuery,我建议使用tinysort:http://tinysort.sjeiti.com/
$("li").tsort({order:"asc"});
$("li").tsort({order:"desc"});
答案 5 :(得分:6)
使用es6语法来求助儿童:
var list = document.querySelector('#test-list')
[...list.children]
.sort((a,b)=>a.innerText>b.innerText?1:-1)
.map(node=>list.appendChild(node))
答案 6 :(得分:3)
这是一个ES6函数,用于对DOM节点进行排序:
const sortChildren = ({ container, childSelector, getScore }) => {
const items = [...container.querySelectorAll(childSelector)];
items
.sort((a, b) => getScore(b) - getScore(a))
.forEach(item => container.appendChild(item));
};
以下是如何使用它来对Untapped user reviews by score进行排序:
sortChildren({
container: document.querySelector("#main-stream"),
childSelector: ".item",
getScore: item => {
const rating = item.querySelector(".rating");
if (!rating) return 0;
const scoreString = [...rating.classList].find(c => /r\d+/.test(c));
const score = parseInt(scoreString.slice(1));
return score;
}
});
答案 7 :(得分:1)
如果没有分析太多,如果这会给表带来任何新东西,我通常会使用它:
function forEach(ar, func){ if(ar){for(var i=ar.length; i--; ){ func(ar[i], i); }} }
function removeElement(node){ return node.parentNode.removeChild(node); }
function insertBefore(ref){ return function(node){ return ref.parentNode.insertBefore(node, ref); }; }
function sort(items, greater){
var marker = insertBefore(items[0])(document.createElement("div")); //in case there is stuff before/after the sortees
forEach(items, removeElement);
items.sort(greater);
items.reverse(); //because the last will be first when reappending
forEach(items, insertBefore(marker));
removeElement(marker);
}
其中item是同一父级的子数组。我们从最后一个开始删除,并从第一个开始追加,以避免在屏幕上可能出现的顶部闪烁。我通常得到这样的项目数组:
forEachSnapshot(document.evaluate(..., 6, null), function(n, i){ items[i] = n; });
答案 8 :(得分:0)
我能想到的最简洁的方法:
参数compare
类似于Array.sort()中使用的比较函数。
排序子节点。
/**
* @param {!Node} parent
* @param {function(!Node, !Node):number} compare
*/
function sortChildNodes(parent, compare) {
const moveNode = (newParent, node) => {
// If node is already under a parent, append() removes it from the
// original parent before appending it to the new parent.
newParent.append(node);
return newParent;
};
parent.append(Array.from(parent.childNodes) // Shallow copies of nodes.
.sort(compare) // Sort the shallow copies.
.reduce(moveNode, document.createDocumentFragment()));
}
排序子元素(子节点的子集)。
/**
* @param {!Element} parent
* @param {function(!Element, !Element):number} compare
*/
function sortChildren(parent, compare) {
const moveElement = (newParent, element) => {
// If element is already under a parent, append() removes it from the
// original parent before appending it to the new parent.
newParent.append(element);
return newParent;
};
parent.append(Array.from(parent.children) // Shallow copies of elements.
.sort(compare) // Sort the shallow copies.
.reduce(moveElement, document.createDocumentFragment()));
}