简体   繁体   中英

How to order divs by id in javascript?

I have this HTML code:

<div id="main">
  <div id="dv_7">...</div>
  <div id="dv_1">...</div>
  <div id="dv_8">...</div>
  <div id="dv_4">...</div>
  <div id="dv_11">...</div>
  <div id="dv_2">...</div>
</div>

How to order the divs in the maindiv with javascript? I have no idea:(

thanks in advance,

Hope this helps. Updated the id to account for alphabetical ordering 1 and 11.

<div id="main">
  <div id="dv_07">7...</div>
  <div id="dv_01">1...</div>
  <div id="dv_08">8...</div>
  <div id="dv_04">4...</div>
  <div id="dv_11">11...</div>
  <div id="dv_02">2...</div>
</div>​

jQuery option:

var mylist = $('#main');
var listitems = mylist.children('div').get();
listitems.sort(function(a, b) {
    var compA = $(a).attr('id').toUpperCase();
    var compB = $(b).attr('id').toUpperCase();
    return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
})
$.each(listitems, function(idx, itm) {
    mylist.append(itm);
});​

Javascript option:

var mylist = document.getElementById('main');
var divs = mylist.getElementsByTagName('div');
var listitems = [];
for (i = 0; i < divs.length; i++) {
        listitems.push(divs.item(i));
}
listitems.sort(function(a, b) {
    var compA = a.getAttribute('id').toUpperCase();
    var compB = b.getAttribute('id').toUpperCase();
    return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
});
for (i = 0; i < listitems.length; i++) {
    mylist.appendChild(listitems[i]);
}​

How about:

var main = document.getElementById( 'main' );

[].map.call( main.children, Object ).sort( function ( a, b ) {
    return +a.id.match( /\d+/ ) - +b.id.match( /\d+/ );
}).forEach( function ( elem ) {
    main.appendChild( elem );
});

Live demo: http://jsfiddle.net/ZEKrH/6/

(You'll need to shim those array methods for IE8.)

the following might work:

var main = document.getElementById("main");
for(var i = 11; i > -1; i--) {
    var div = document.getElementById("dv_" + i);
    if(div != null)
        main.appendChild(div);
}

For a solution that works for any arbitrary number of child divs with numbers in any range, you can use a function like this (that actually parses the number of our the ID and does a true numeric sort on it):

function sortChildrenDivsById(parentId) {
    var parent = document.getElementById(parentId);
    // get child divs
    var children = parent.getElementsByTagName("div");
    var ids = [], obj, i, len;
    // build an array of objects that has both the element 
    // and a parsed div number in it so we can sort
    for (i = 0, len = children.length; i < len; i++) {
        obj = {};
        obj.element = children[i];
        obj.idNum = parseInt(children[i].id.replace(/[^\d]/g, ""), 10);
        ids.push(obj);
    }
    // sort the array
    ids.sort(function(a, b) {return(a.idNum - b.idNum);});
    // append in sorted order
    for (i = 0; i < ids.length; i++) {
         parent.appendChild(ids[i].element);
    }
}

Working example here: http://jsfiddle.net/jfriend00/v9mCM/

FYI, this is cross-browser, plain javascript and will even work in old browsers without shims.


Here's another way of doing it with slightly less code:

function sortChildrenDivsById(parentId) {
    var parent = document.getElementById(parentId);
    var children = parent.getElementsByTagName("div");
    var ids = [], i, len;
    for (i = 0, len = children.length; i < len; i++) {
        ids.push(parseInt(children[i].id.replace(/^.*_/g, ""), 10));
    }
    ids.sort(function(a, b) {return(a - b);});
     for (i = 0, len = ids.length; i < len; i++) {
         parent.appendChild(document.getElementById("dv_" + ids[i]));
     }
}

Working example: http://jsfiddle.net/jfriend00/TqJVb/

All the ids nums are parsed out and put into an array which is sorted and then each object is looked up by id and reinserted in sorted order. This wouldn't be quite as fast as the first one, but it's less code.

The following is compatible with browsers back to IE 5 and similar, no shims or libraries. The sort function can be modified to sort numerically, at present it will sort the divs as 1, 11, 2, 4, etc. It's not too hard to change it so they are sorted 1, 2, 4, ... 11.

function sortDivs(div) {
  var divs = div.getElementsByTagName('div');
  var a = [];
  for (var i=0, iLen=divs.length; i<iLen; i++) { 
    a[i] = divs[i];
  }
  a.sort(function(a, b) {
    return a.id < b.id? -1 : a.id == b.id? 0 : 1;
  });
  while (iLen--) {
    div.insertBefore(a[iLen], div.firstChild);
  }
}

window.onload = function() {
  sortDivs(document.getElementById('main'));
}

Edit

Minimalist version for those who think it matters with comments and numeric sort.

function sortDivs(div) {
  var divs = div.getElementsByTagName('div');

  // Convert divs collection to an array
  for (var i=0, iLen=divs.length, a=[]; i<iLen; i++) a[i] = divs[i];

  // Sort the array numerically
  a.sort(function(a, b) {
    return a.id.split('_')[1] - b.id.split('_')[1]; 
  });

  // Move elements to sorted order
  while (iLen--) div.insertBefore(a[iLen], div.firstChild);
}

2021 answer

function sortChildren(parent, comparator) {
    parent.replaceChildren(...Array.from(parent.children).sort(comparator));
}

That's all you need. Example:

const main = document.getElementById('main');
sortChildren(main, (a, b) => +a.id.match( /\d+/ ) - +b.id.match( /\d+/ ));
<div id="main">
  <div id="dv_7" data-order=7>7</div>
  <div id="dv_1" data-order=1>1</div>
  <div id="dv_8" data-order=8>8</div>
  <div id="dv_4" data-order=4>4</div>
  <div id="dv_11" data-order=11>11</div>
  <div id="dv_2" data-order=2>2</div>
</div>

<button onclick="sort()">
Sort
</button>

function sort() {

  var main = document.getElementById( 'main' );

  [].map.call( main.children, Object ).sort( function ( a, b ) {
console.log(a.dataset.order);
      return +a.dataset.order - +b.dataset.order;
  }).forEach( function ( elem ) {
      main.appendChild( elem );
  });

}

Updated @Šime Vidas answer to support dynamic order with button and Data Attribute

http://jsfiddle.net/hbe4w90s/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM