最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript: how to sort elements of a class - Stack Overflow

programmeradmin3浏览0评论

I have a blog which produces a list like this on a php/html page

<div id="unique-id-4" class="blog-entry">Bert blah blah</div>
<div id="unique-id-2" class="blog-entry">Andy blah blah</div>
<div id="unique-id-3" class="blog-entry">Chas blah blah</div>
<div id="unique-id-1" class="blog-entry">Dave blah blah</div>

I want to reorder the divs on the page using javascript.

Firstly, to see how it works, an alphabetical sort. (That may be enough for this question). But secondly (what I really want to do) sort them by "age". I have an array of each person's name and age which I can reference. Is this even possible?

I found this when looking for finding by class

var content = document.getElementsByClassName('blog-entry')

The sorted output could be on the same page, or on a different page - it doesn't matter. thanks for any help. I know very little about javascript.

I'd like to sort in the order 1) Andy, Bert, Chas, Dave (i.e. "alphabetically) producing:

<div id="unique-id-2" class="blog-entry">Andy blah blah</div>
<div id="unique-id-4" class="blog-entry">Bert blah blah</div>
<div id="unique-id-3" class="blog-entry">Chas blah blah</div>
<div id="unique-id-1" class="blog-entry">Dave blah blah</div>

and ideally

2) By their ages, where in a separate array: Andy = 42, Bert =18, Chas = 73, Dave = 56; producing

<div id="unique-id-4" class="blog-entry">Bert blah blah</div>
<div id="unique-id-2" class="blog-entry">Andy blah blah</div>
<div id="unique-id-1" class="blog-entry">Dave blah blah</div>
<div id="unique-id-3" class="blog-entry">Chas blah blah</div>

I have a blog which produces a list like this on a php/html page

<div id="unique-id-4" class="blog-entry">Bert blah blah</div>
<div id="unique-id-2" class="blog-entry">Andy blah blah</div>
<div id="unique-id-3" class="blog-entry">Chas blah blah</div>
<div id="unique-id-1" class="blog-entry">Dave blah blah</div>

I want to reorder the divs on the page using javascript.

Firstly, to see how it works, an alphabetical sort. (That may be enough for this question). But secondly (what I really want to do) sort them by "age". I have an array of each person's name and age which I can reference. Is this even possible?

I found this when looking for finding by class

var content = document.getElementsByClassName('blog-entry')

The sorted output could be on the same page, or on a different page - it doesn't matter. thanks for any help. I know very little about javascript.

I'd like to sort in the order 1) Andy, Bert, Chas, Dave (i.e. "alphabetically) producing:

<div id="unique-id-2" class="blog-entry">Andy blah blah</div>
<div id="unique-id-4" class="blog-entry">Bert blah blah</div>
<div id="unique-id-3" class="blog-entry">Chas blah blah</div>
<div id="unique-id-1" class="blog-entry">Dave blah blah</div>

and ideally

2) By their ages, where in a separate array: Andy = 42, Bert =18, Chas = 73, Dave = 56; producing

<div id="unique-id-4" class="blog-entry">Bert blah blah</div>
<div id="unique-id-2" class="blog-entry">Andy blah blah</div>
<div id="unique-id-1" class="blog-entry">Dave blah blah</div>
<div id="unique-id-3" class="blog-entry">Chas blah blah</div>
Share Improve this question edited Jan 15, 2012 at 21:14 Gabe asked Jan 15, 2012 at 17:39 GabeGabe 511 gold badge1 silver badge4 bronze badges 1
  • See this working jsfiddle. – Shiplu Mokaddim Commented Jan 15, 2012 at 18:40
Add a ment  | 

6 Answers 6

Reset to default 3

While I'm not entirely sure what you intend to sort by this should cover all angles.

/*Sort my entries
  sortProperty = DOM object property that is to be used to sort in ascending order
*/
function sortMyEntries(sortProperty)
{
    var blogEntries = document.getElementsByClassName("blog-entry");
    blogEntries = Array.prototype.slice.call(blogEntries,0)
    blogEntries.sort(function(a,b)
         {
             return (a[sortProperty] > b[sortProperty]);
         })
    return blogEntries;
}

This method is currently limited to dealing with a question specific selector but it is fairly flexible. For example both of the following are applicable

sortMyEntries("id");  //Sort blog entries by DOM object id
sortMyEntries("innerHTML");  //Sort blog entries by DOM object innerHTML

Using no magic or unsupport methods:

var elements = document.getElementsByTagName('div');
var filtered = [];
for (var i = 0; i < elements.length; i++) {
    if (elements[i].className === "blog-entry") {
       filtered.push(elements[i]);
    }  
}
var sorted = filtered.sort(function (a, b) {
   return a.innerHTML > b.innerHTML; 
});

var parent = elements[0].parentNode;

for (i = 0; i < sorted.length; i++) {
    parent.appendChild(sorted[i]);
}

JsFiddle demo

Node information


For an array based sort:

var people = [{name: "Andy", age: 20}, {name: "Bob", age: 67}];

var sorted = filtered.sort(function (a, b) {
   return people[a.innerHTML].age > people[b.innerHTML].age; 
});

First thing, content is not an array here. It is NodeList. So the steps to do.

  1. Convert NodeList to array
  2. Sort array
  3. Remove all blog entries
  4. Add from sorted array

    <div id="blogs">
     <div id="unique-id-4" class="blog-entry">Bert blah blah</div>
     <div id="unique-id-2" class="blog-entry">Andy blah blah</div>
     <div id="unique-id-3" class="blog-entry">Chas blah blah</div>
     <div id="unique-id-1" class="blog-entry">Dave blah blah</div>
    </div>
    
    
    var blogs = document.getElementById("blogs");
    var blogEntries = blogs.getElementsByClassName('blog-entry');
    blogEntries = Array.prototype.slice.call(blogEntries);
    if(blogEntries && blogEntries.length){
      blogEntries.sort(sortBlogs);
      while (blogs.hasChildNodes()) {
         blogs.removeChild(blogs.lastChild);
      }
      while(blogEntries.length){
         var blogEntry = blogEntries.shift();
         blogs.appendChild(blogEntry);
      }
    }
    
    function sortBlogs(a, b){
      var aid = parseInt(a.id.replace("unique-id-", ""));
      var bid = parseInt(b.id.replace("unique-id-", ""));
      return aid - bid;  
    }
    

See a demo here : http://jsfiddle/diode/8W6AU/7/ Modify the function sortBlogs for the sorting needed. Now it uses id for sorting.

  1. var content = document.getElementsByClassName('blog-entry') will give you node list of HTMLElement object in content.
  2. Convert it to Array.
  3. Sort it using the Array.sort function.
  4. On the callback, pare the objects using their innerHTML property.

http://jsfiddle/myk2X/3/ is a working example. The silver container holds the initial objects, and the light green container holds the result.

It depends how your arrays are stored (does unique-id-X correspond to ages[X]?) but here's the general method: pass a custom parison function to Array.sort.

function toArray(obj) {
    var r = [], i = 0, l = obj.length;

    for(; i < l; i++) {
        if(i in obj) {
            r[i] = obj[i];
        }
    }

    return r;
}

var elements = toArray(document.getElementsByClassName('blog-entry')); // Doesn't have full browser support, so you might want to use jQuery, e.g. here.
var ages = [...];
var names = [...];

elements.sort(function(element1, element2) {
    var index1 = elements.indexOf(element1); 
    var index2 = elements.indexOf(element2);

    // Sort by name first:
    if(names[index1] < names[index2]) { // Can do case-insensitive parison here, too.
        return -1;
    } else if(names[index1] > names[index2]) {
        return 1;
    } else if(ages[index1] < ages[index2]) {
        // Names were equal, sort by age.
        return -1;
    } else if(ages[index1] > ages[index2]) {
        return 1;
    } else {
        // They're equal.
        return 0;
    }
}).forEach(function(element) {
    // This is where the magic happens! appendChild() is just called in order.
    // The best part is that it looks like it does almost nothing.
    element.parentNode.appendChild(element);
});

Of course, there are two things that might not work in IE. (Happy, Raynos?) One is document.getElementsByClassName, and the other is Array.forEach. Those aren't supported in some browsers, i.e. IE. Here's a patibility script for Array.forEach:

if(![].forEach) {
    Array.prototype.forEach = function(action, thisArg) {
        for(var i = 0, l = this.length; i < l; i++) {
            if(i in this) {
                action.call(thisArg, this[i], i, this);
            }
        }
    };
}

Seems like the ideal opportunity to use jQuery and a plugin along the lines of TinySort.

发布评论

评论列表(0)

  1. 暂无评论