JavaScript to sort DOM elements by some comparator, without jQuery

雨燕双飞 提交于 2019-11-28 03:56:08

问题


Imagine some DOM elements:

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

How can these elements be sorted using JavaScript and without jQuery?

Something similar to:

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

回答1:


You should use the ordering capabilities of flexboxes. This will allow to re-order the elements without moving them around in the DOM. This involves setting the CSS order property.

See https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes for more details.




回答2:


Some time ago I wrote this:

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);
}

Basically:

  1. First create an array to store the elements with its corresponding value returned by the comparator function.

    We could also run the function when sorting, but since DOM interactions are slow, this way we make sure the function will only run once per element.

  2. Then, we sort it using native sort.

    If isNum argument is truly, we use a sorting function that compares numerically. This is needed if the comparator function returns strings but you want to compare numerically instead of lexicographically.

  3. Now, we remove the wrapper element from the DOM. This way reordering the children will be less expensive (e.g. avoiding repaitings).

  4. Finally we reorder the children, and insert wrapper back in its place.

Run it like

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

or

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

Demo




回答3:


<!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>


来源:https://stackoverflow.com/questions/24342242/javascript-to-sort-dom-elements-by-some-comparator-without-jquery

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!