1 | /** |
---|
2 | * jQuery.fn.sortElements |
---|
3 | * -------------- |
---|
4 | * @param Function comparator: |
---|
5 | * Exactly the same behaviour as [1,2,3].sort(comparator) |
---|
6 | * |
---|
7 | * @param Function getSortable |
---|
8 | * A function that should return the element that is |
---|
9 | * to be sorted. The comparator will run on the |
---|
10 | * current collection, but you may want the actual |
---|
11 | * resulting sort to occur on a parent or another |
---|
12 | * associated element. |
---|
13 | * |
---|
14 | * E.g. $('td').sortElements(comparator, function(){ |
---|
15 | * return this.parentNode; |
---|
16 | * }) |
---|
17 | * |
---|
18 | * The <td>'s parent (<tr>) will be sorted instead |
---|
19 | * of the <td> itself. |
---|
20 | */ |
---|
21 | jQuery.fn.sortElements = (function(){ |
---|
22 | |
---|
23 | var sort = [].sort; |
---|
24 | |
---|
25 | return function(comparator, getSortable) { |
---|
26 | |
---|
27 | getSortable = getSortable || function(){return this;}; |
---|
28 | |
---|
29 | var placements = this.map(function(){ |
---|
30 | |
---|
31 | var sortElement = getSortable.call(this), |
---|
32 | parentNode = sortElement.parentNode, |
---|
33 | |
---|
34 | // Since the element itself will change position, we have |
---|
35 | // to have some way of storing its original position in |
---|
36 | // the DOM. The easiest way is to have a 'flag' node: |
---|
37 | nextSibling = parentNode.insertBefore( |
---|
38 | document.createTextNode(''), |
---|
39 | sortElement.nextSibling |
---|
40 | ); |
---|
41 | |
---|
42 | return function() { |
---|
43 | |
---|
44 | if (parentNode === this) { |
---|
45 | throw new Error( |
---|
46 | "You can't sort elements if any one is a descendant of another." |
---|
47 | ); |
---|
48 | } |
---|
49 | |
---|
50 | // Insert before flag: |
---|
51 | parentNode.insertBefore(this, nextSibling); |
---|
52 | // Remove flag: |
---|
53 | parentNode.removeChild(nextSibling); |
---|
54 | |
---|
55 | }; |
---|
56 | |
---|
57 | }); |
---|
58 | |
---|
59 | return sort.call(this, comparator).each(function(i){ |
---|
60 | placements[i].call(getSortable.call(this)); |
---|
61 | }); |
---|
62 | |
---|
63 | }; |
---|
64 | |
---|
65 | })(); |
---|