Javascript - sorting a collection of divs - Stack Overflow

I am trying to learn Javascript alone so please don't suggest a library or jQuery.I have a list of

I am trying to learn Javascript alone so please don't suggest a library or jQuery.

I have a list of divs and I want the user to be able to sort them by their value. For example:

<button onclick="sort();">Test</button>
<div class="num">2</div>
<div class="num">3</div>
<div class="num">8</div>
<div class="num">1</div>

JS:

function sort(){
   var elements = document.getElementsByClassName("num");
   elements.sort();
}

I cannot find a straight answer to what's wrong with this. Does getElementsByClassName return an array of the values of each div with that name? How, when the array is then sorted, so I reflect the changes in the divs?

I am trying to learn Javascript alone so please don't suggest a library or jQuery.

I have a list of divs and I want the user to be able to sort them by their value. For example:

<button onclick="sort();">Test</button>
<div class="num">2</div>
<div class="num">3</div>
<div class="num">8</div>
<div class="num">1</div>

JS:

function sort(){
   var elements = document.getElementsByClassName("num");
   elements.sort();
}

I cannot find a straight answer to what's wrong with this. Does getElementsByClassName return an array of the values of each div with that name? How, when the array is then sorted, so I reflect the changes in the divs?

Share Improve this question edited Jun 4, 2013 at 3:49 Samuel Liew 79.2k111 gold badges169 silver badges304 bronze badges asked Jun 4, 2013 at 3:43 user2450099user2450099 3853 gold badges7 silver badges17 bronze badges 2
  • 2 This site isn't a teaching site, don't expect us to teach you javascript. – gdoron Commented Jun 4, 2013 at 3:45
  • 1 I'm not. What I am asking for is a solution to a problem that I haven't been able to find useful answers to via Google. – user2450099 Commented Jun 4, 2013 at 3:54
Add a ment  | 

3 Answers 3

Reset to default 6

You can't use the sort() function on a NodeList, which is what you are actually getting by calling getElementsByClassName or querySelectorAll.

So you'll have to convert it to an array before using Array.sort():

// Get elements and convert to array
const elems = [...document.querySelectorAll(".num")];

// Sort elements in-place
elems.sort((a, b) => Number(a.innerText) - Number(b.innerText));

// Join the array back into HTML
const outputHtml = elems.reduce((a, el) => a + el.outerHTML, "");

// Append HTML to parent container
document.getElementById('myDiv').innerHTML = outputHtml;

http://jsfiddle/g918jmoL/

Sorting nodes is not that simple, you may need to deal with other nodes that might get in the way. Anyhow, here's a function that accepts a NodeList or HTMLCollection, converts it to an array, sorts it, then puts the nodes back in order. Note that the elements are put back at the bottom of the parent element, so any other elements will end up at the top. Anyhow, it demonstrates an approach that you can adapt.

There are many other approaches, including others using DOM methods, beware of any that are based on munging the markup. Also, beware of cloning elements as this may have unwele side effects on listeners (they may or may not be removed, depending on the browser and how they've been added).

<script type="text/javascript">

function getText(el) {
  return el.textContent || el.innerText || '';
}

function sortElements(nodeList) {
  // Assume there's a mon parent
  var node, parentNode = nodeList[0].parentNode

  // Define a sort function
  function sortEls(a, b) {
    var aText = getText(a);
    var bText = getText(b);
    return aText == bText? 0 : aText < bText? -1 : 1;
  }

  // Convert nodelist to an array and remove from the DOM at the same time
  var a = [], i = nodeList.length;
  while (i--) {
    a[i] = parentNode.removeChild(nodeList[i]);

  }

  // Sort the array
  a.sort(sortEls);

  // Put elements back in order
  i = 0;
  while (node = a[i++]) {
    parentNode.appendChild(node);
  }
}

</script>

<div>0</div>
<div>4</div>
<div>2</div>
<div>3</div>
<div>5</div>
<button onclick="sortElements(document.getElementsByTagName('div'))">Sort</button>

The problem is that getElementsByClassName return a nodeList, not an array. Ok, I have to say, that is very stupid and I still can't get my head around why browser implemented it this way...

What you can do though, is first convert the nodeList to an array and than do the sorting:

var elems = Array.prototype.slice.call(elements);
elems.sort(/* function (a, b) {} */);

Note that the sorting function is optionnal and is passed normally after the first value. (Although, called directly on your elements list, .sort() won't sort anything without a function parameter as it won't know which one will e before the other)

Checkout MDN call description to understand how this really works behind the scene: https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744262790a4565718.html

相关推荐

  • Javascript - sorting a collection of divs - Stack Overflow

    I am trying to learn Javascript alone so please don't suggest a library or jQuery.I have a list of

    8天前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信