jQuery - sort DIVs by className

2020-02-06 03:12发布

I have a list of DIVs, like this :

<div id="list">
    <div class="cat1-4.2"><div>4</div></div>
    <div class="cat3-3.3"><div>3</div></div>
    <div class="cat2-5.1"><div>5</div></div>
    <div class="cat3-1.5"><div>1</div></div>
    <div class="cat3-2.4"><div>2</div></div>
</div>

and I want to sort them, using jQuery

Server-side, I can define the wanted order, and include this order in the class names :

catX-4.2

I want to be able to call either the first order (in my example this DIV will be in the 4th position), or the second order (it will be in the 2nd position) : that explains the "4.2"

So if I call OrderDIV(1) I will have this :

1
2
3
4
5

and if I call OrderDIV(2) I will have this :

5
4
3
2
1

(I will need to add more orders, like : catX-4.2.5.6.2)

Thank you VERY MUCH for your help!

标签: jquery
3条回答
可以哭但决不认输i
2楼-- · 2020-02-06 03:53

jQuery abstracts the Array.prototype.sort() method so you can use it on wrapped sets:

var OrderDIV = function(asc) {
    $('div#list').children().detach().sort(function(a,b) {
        return asc ? (+a.textContent) - (+b.textContent) : (+b.textContent) - (+a.textContent);
    }).appendTo(document.body);
}

OrderDIV(0);

Demo: http://jsfiddle.et/Ls2kd/9/

For simplicity I ordered the <div> nodes by their content. If you need to use the ID it shouldn't be a problem at all. Just access a.id and strip out the part you need for comparison (regex for instance).

Another thing to mention, InternetExplorer isn't aware of .textContent therefore should it be a.textContent || a.text.

查看更多
时光不老,我们不散
3楼-- · 2020-02-06 04:03
jQuery.fn.sortElements = (function(){

    var sort = [].sort;

    return function(comparator, getSortable) {

        getSortable = getSortable || function(){return this;};

        var placements = this.map(function(){

            var sortElement = getSortable.call(this),
                parentNode = sortElement.parentNode,

                // Since the element itself will change position, we have
                // to have some way of storing its original position in
                // the DOM. The easiest way is to have a 'flag' node:
                nextSibling = parentNode.insertBefore(
                    document.createTextNode(''),
                    sortElement.nextSibling
                );

            return function() {

                if (parentNode === this) {
                    throw new Error(
                        "You can't sort elements if any one is a descendant of another."
                    );
                }

                // Insert before flag:
                parentNode.insertBefore(this, nextSibling);
                // Remove flag:
                parentNode.removeChild(nextSibling);

            };

        });

        return sort.call(this, comparator).each(function(i){
            placements[i].call(getSortable.call(this));
        });

    };

})();

Use this sort criteria for your needs:

function sortCriteria(k) {
    var regex = /\b\d+/g;
    return function(a, b){
        return parseInt(a.id.match(regex)[k]) > parseInt(b.id.match(regex)[k]) ? 1 : -1;
    }
}

$("#list >").sortElements(sortCriteria(0));
查看更多
叼着烟拽天下
4楼-- · 2020-02-06 04:07

You changed the requirements mid way ... just like a true client. Updated version with some comments attached. Just to confirm, there are two "configurable" variables at the front.

classPrefix: the "prefix" unique to the class used to determine sort order ('cat' in this case) listElementSelector: the jQuery selector used to obtain the list to sort.

function OrderDIV(position)
{
    var classPrefix = 'cat';
    var listElementSelector = '#list';

    // -- Decrement the position to make it 0 based
    position--;

    // -- Parses the "position" section from the given classes, and
    //    then the position at the specific index requested.
    var parsePosition = function(classes, pos) {
        // -- Split the "classes" into an array.
        var classList = classes.split(' ');

        // -- Determine which of the "classes" starts with the prefix we want.
        for( var i in classList )
        {
            if( classList[i].substr(0, classPrefix.length) == classPrefix )
            {
                // -- Strip out the positions section, and split it.
                var positions = classList[i].split('-')[1].split('.');

                // -- return the one position we want
                return positions[pos];
            }
        }

        // -- In the event that we don't find the class we're looking for ...
        return -1;
    }

    // -- Compares div A to div B, and returns an indicator of the order
    var funcSort = function(a, b) {
        // -- Use "parsePosition" to determine the sortable criteria from the classes.
       var compA = parsePosition($(a).attr('class'), position);
       var compB = parsePosition($(b).attr('class'), position);
       return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
    };

    // -- Select the list element.
    var list = $(listElementSelector);

    // -- Select the list items, and return them as an array.
    var listitems = list.children('div').get();

    // -- Sort the array using the "funcSort".
    listitems.sort(funcSort);

    // -- Go through each of the array entries, and "append" them to the list container
    //   (this moves them to the 'back' of the list)
    $.each(listitems, function(idx, itm) { list.append(itm); });
}
查看更多
登录 后发表回答