jQuery sorting of div elements based on count, and date/time (timestamp)

后端 未结 2 2055
感情败类
感情败类 2021-01-06 18:46

I currently use the sort function to sort my div elements based on the count value. Here\'s how it\'s being done now: (I\'m not sure if it\'s an efficient method or not..)

2条回答
  •  清酒与你
    2021-01-06 19:23

    Only the sort comparator function needs to change. I'm sure there are plugins available to do this, and you might want to take a look at them, but implementing what you want is fairly trivial. The sortDescending method gets two divs each time, and comparison must follow the criteria you've specified:

    1. First by count
    2. If count is equal, then by timestamp
    3. If timestamps are equal, then return 0

    Here's the ugly straightforward non-optimized version:

    function sortDescending(a, b) {
        if(getCount(a) < getCount(b)) {
            return -1;
        }
        else if(getCount(a) > getCount(b)) {
            return 1;
        }
        else if(getTimestamp(a) < getTimestamp(b)) {
            return -1;
        }
        else if(getTimestamp(a) > getTimestamp(b) {
            return 1;
        }
        else {
            return 0;
        }
    }
    

    If you see the if-else structure, it may seem obvious that you can genericize this approach to be able to handle any type of custom ordering. So here's a jab at a sortBy method that takes in a number callback functions, where each callback defines one sorting criteria.

    function sortBy() {
        var callbacks = arguments;
    
        return function(a, b) {
            for(var i = 0; i < callbacks; i++) {
                var value = callbacks[i](a, b);
                if(value != 0) {
                    return value;
                }
            }
            return 0;
        };
    }
    

    Then pass all criteria's as callbacks to this sortBy function. Here's a rough example for your code:

    function compareCount(a, b) {
        return getCount(a) - getCount(b);
    }
    
    function compareTimestamp(a, b) {
        return getTimestamp(a) - getTimestamp(b);
    }
    
    $("selector").sort(sortBy(compareCount, compareTimestamp));
    

    And while we are at it, let's also make a jQuery plugin out of this. It will have a nice and easy interface:

    $("parent selector").sortBy("child selector 1", "child selector 2", ...);
    

    The idea is to pass a jQuery selector that will select a node whose text will determine the value to sort by. We will give integers a higher priority and first try to sort numerically if both values are so, otherwise do a regular comparison.

    jQuery.fn.sortBy = function() {  
        var selectors = arguments;
    
        this.sort(function(a, b) {
            // run through each selector, and return first non-zero match
            for(var i = 0; i < selectors.length; i++) {
                var selector = selectors[i];
    
                var first = $(selector, a).text();
                var second = $(selector, b).text();
    
                var isNumeric = Number(first) && Number(second);
                if(isNumeric) {
                    var diff = first - second;
                    if(diff != 0) {
                        return diff;
                    }
                }
                else if(first != second) {
                    return first < second ? -1 : 1;
                }
            }
    
            return 0;
        });
    
        this.appendTo(this.parent());
    
        return this;
    };
    

    Use as

    $('#list .list_item').sortBy('.count', '.timestmap');
    

    See an example of the plugin here.

    Btw, none of this will actually sort the elements in the document itself. See this question for how to do that.

提交回复
热议问题