Sort DOM elements to order array with jQuery

2020-02-11 08:29发布

问题:

A moment ago I asked this question: javascript sort array to align with order array based on what turned out to be a false premise. (I've been up for too long, give me a break please).

What I really need to do is sort DOM elements. Performance is key in my application as it will be running in very CPU-poor situations. So what I have is something like this:

<div id="moduleWrap">
    <div class="module">Jack</div>    <!-- 0 -->
    <div class="module">Jill</div>    <!-- 1 -->
    <div class="module">Nancy</div>   <!-- 2 -->
    <div class="module">Tom</div>     <!-- 3 -->
    <div class="module">Cartman</div> <!-- 4 -->
</div>

And in JavaScript:

$modules = $('#moduleWrap .module');
order    = [3,1,4,0,2];

What I need is this:

<div id="moduleWrap">
    <div class="module">Tom</div>     <!-- 3 -->
    <div class="module">Jill</div>    <!-- 1 -->
    <div class="module">Cartman</div> <!-- 4 -->
    <div class="module">Jack</div>    <!-- 0 -->
    <div class="module">Nancy</div>   <!-- 2 -->
</div>

I thought (wrongly) that I could sort the jQuery object and simply append the result. This is not so.

回答1:

I would just iterate over the order array and rearrange the DOM elements accordingly:

var elements = [];
$.each(order, function(i, position) {
    elements.push($modules.get(position));
});

$('#moduleWrap').append(elements);

DEMO

To increase performance, you can take away more and more jQuery. For example:

var wrapper = document.getElementById('moduleWrap');
for(var i = 0, l = order.length; i < l; i++) {
    wrapper.appendChild($modules.get(order[i]));
}

DEMO

jQuery is great because it makes things easy, but if you need high performance, you should rather go without it.



回答2:

Try this.

Detaching the elements from the DOM tree may speed up the process.

$modules.detach();

var len = order.length,
    temp = [];

for( var i = 0; i < len; i++ ) {
  temp.push( $modules[ order[i] ] );
}

$("#moduleWrap").append( temp );

Fiddle here http://jsfiddle.net/rEFu3/ ​



回答3:

I know this is late, but maybe it will help someone. I was trying to do a similar thing and #Felix Kling's answer got me 90% there. But in my case I have a div id which is equal to the order values, like this:

order    = [3,1,4,0,2];

<div id="0" class="module">Jack</div>    <!-- 0 -->
<div id="1" class="module">Jill</div>    <!-- 1 -->
<div id="2" class="module">Nancy</div>   <!-- 2 -->
<div id="3" class="module">Tom</div>     <!-- 3 -->
<div id="4" class="module">Cartman</div> <!-- 4 -->

then I can simply push the element using the position value

var elements = [];
$.each(order, function(i, position) {
    elements.push($('#'+position));
});

$('#moduleWrap').append(elements);