JavaScript通过一些比较器对DOM元素进行排序,不需要jQuery

JavaScript to sort DOM elements by some comparator, without jQuery

本文关键字:排序 jQuery 不需要 元素 DOM 比较器 JavaScript      更新时间:2023-09-26

想象一些DOM元素:

<ul id="list">
  <li data-index="3">Baz</li>
  <li data-index="1">Foo</li>
  <li data-index="2">Bar</li>
</ul>

这些元素如何使用JavaScript和没有jQuery排序?

类似:

document.getElementById('list').sort(function(li) { return li.dataset.index; });

您应该使用flexbox的订购功能。这将允许对元素重新排序,而无需在DOM中移动它们。这包括设置CSS的order属性。

前段时间我写过:

function sortChildren(wrap, f, isNum) {
    var l = wrap.children.length,
        arr = new Array(l);
    for(var i=0; i<l; ++i)
        arr[i] = [f(wrap.children[i]), wrap.children[i]];
    arr.sort(isNum
        ? function(a,b){ return a[0]-b[0]; }
        : function(a,b){ return a[0]<b[0] ? -1 : a[0]>b[0] ? 1 : 0; }
    );
    var par = wrap.parentNode,
        ref = wrap.nextSibling;
    par.removeChild(wrap);
    for(var i=0; i<l; ++i) wrap.appendChild(arr[i][1]);
    par.insertBefore(wrap, ref);
}
基本上

:

  1. 首先创建一个数组来存储由比较器函数返回的具有相应值的元素。

    我们也可以在排序时运行这个函数,但是由于DOM交互很慢,这样我们就可以确保这个函数对每个元素只运行一次。

  2. 然后,我们使用本地sort进行排序。

    如果isNum参数为真,则使用排序函数进行数值比较。如果comparator函数返回字符串,但您希望按数字方式而不是按字典顺序进行比较,则需要此操作。

  3. 现在,我们从DOM中删除包装器元素。这样,重新排序子代将更便宜(例如,避免修理)。

  4. 最后我们重新排序子节点,并将wrapper插入到原来的位置。

那样运行
sortChildren(
    document.getElementById('list'),
    function(li) { return li.dataset.index; },
    true
);

sortChildren(
    document.getElementById('list'),
    function(li) { return +li.dataset.index; }
);

<!doctype html>
<html lang="en">
<head>
<meta charset= "utf-8">
<title>sort list</title>
</head>
<body>
<strong>Double click the list to sort by data-index</strong>
<ul id= "list">
<li data-index= "3">Baz</li>
<li data-index= "1">Foo</li>
<li data-index= "2">Bar</li>
</ul>
<script>
document.body.ondblclick=function(){
    var A=[], pa= document.getElementById('list');
    var itemz= pa.getElementsByTagName('li');
    A.slice.call(itemz).sort(function(a, b){
        return a.getAttribute('data-index')-b.getAttribute('data-index');
    }).forEach(function(next){
            pa.appendChild(next);
    });
}
</script>
</body>
</html>