• Baz
  • JavaScript to sort DOM elements using some comparator without jQuery

    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 like:

     document.getElementById('list').sort(function(li) { return li.dataset.index; }); 
    +6
    source share
    3 answers

    You should use the flexboxes collation capabilities. This will allow you to reorder items without moving them to the DOM. This includes setting the CSS order property.

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

    +5
    source

    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:

    • First, create an array to hold items with the corresponding value returned by the comparator function.

      We could also run this function when sorting, but since the DOM interactions are slow, we make sure that the function will be executed only once for each element.

    • Then we sort it with native sort .

      If the argument isNum valid, we use a sort function that compares numerically. This is necessary if the comparator function returns strings, but you want to compare numerically, not lexicographically.

    • Now we remove the shell element from the DOM. Thus, reordering children will be less expensive (e.g. avoiding repetitions).

    • Finally, we reorder the children and insert the wrapper 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
    source
     <!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> 
    0
    source

    Source: https://habr.com/ru/post/971138/


    All Articles