jQuery insert div at right place in list of divs

2019-09-12 11:35发布

I have a list of dozens DIVs like

<div data-sort="7.5"></div>
<div data-sort="3.2"></div>
<div data-sort="2.15"></div>
<div data-sort="-1.78"></div>
<div data-sort="-2.39"></div>

and so on and I get new DIVs with an ajax request. I need to insert the new DIV so the order with "data-sort" remains intact in descending order.

5条回答
霸刀☆藐视天下
2楼-- · 2019-09-12 12:14

Maybe not elegant, but fast enough...

In your success handler:

...
success: function(data) {
    $(data).each(function(){
        var $adiv = $(this);
        var sortval = parseFloat($adiv.data("sort"));
        var last = true;
        $("div").each(function(){
            if ($(this).data("sort") < sortval) {
                $(this).prepend($adiv);
                last = false;
                return false;
            }
        });
        if(last) {
            $("div").last().append($adiv);
        }
    });
}

jsFiddle

查看更多
beautiful°
3楼-- · 2019-09-12 12:17

It's not as optimal as can be, but I would just sort the divs each time the ajax request completes:

$("div").sort(function (prev, next) {
    return parseInt(next.dataset.sort) - parseInt(prev.dataset.sort);
}).appendTo("body");

If that takes too long, you'll just have to cycle through the divs (via .each?) and find the first one whose data-sort is smaller.

查看更多
来,给爷笑一个
4楼-- · 2019-09-12 12:18

You can use your custom logic also. Please try it.

Here is your HTML

<div id="dvBase">
        <div data-sort="7.5">
        </div>
        <div data-sort="3.2">
        </div>
        <div data-sort="2.15">
        </div>
        <div data-sort="-1.78">
        </div>
        <div data-sort="-2.39">
        </div>
    </div>
    <div id="tempDiv">
    </div>

javascript code

var divToAdd = "<div data-sort=\"1.5\"></div>";
        function getValue() {

            $("#tempDiv").html(divToAdd);
            var returnvalue = $("#tempDiv div").attr("data-sort");
            $("#tempDiv").empty();
            return returnvalue;
        }
        $(document).ready(function () {
            var valueToadd = parseFloat(getValue());
            var count = $("#dvBase >div[data-sort]").length;

            $("#dvBase >div[data-sort]").each(function (index, obj) {
                var value1 = parseFloat($(obj).attr("data-sort"));
                if (index < count - 1) {
                    var value2 = parseFloat($(obj).next().attr("data-sort"));

                    if ((value1 == valueToadd || (valueToadd < value1 && valueToadd >= value2)) && $("#dvBase >div[data-sort]").length === count) {
                        $(obj).after(divToAdd);
                    }
                } else {
                    if ($("#dvBase >div[data-sort]").length === count) {
                        $(obj).after(divToAdd);
                    }
                }
            });
        });
查看更多
孤傲高冷的网名
5楼-- · 2019-09-12 12:24

The fastest algorithm to do this insertion (O(logN)) would be to do a binary search for the values that the new item goes between. Assume that the list is already sorted first (if that's not done automatically, use one of the other answers here):

/**+
 * Boilerplate to check first/last value
 */
var sortval = $new.data('sort');
var $first = $("div:first");
if (sortval >= $first.data('sort')) {
   $new.insertBefore($first);
    return;
}

var $last = $("div:last");
if (sortval <= $last.data('sort')) {
   $new.insertAfter($last);
    return;
}
/*-*/

//Fun stuff
var count = 0;
var $div = $("div");
do {
   var index = parseInt($div.length / 2)
   var $compare = $div.eq(index);
   var compare = $compare.data('sort');
   if (sortval === compare) {
      break;
   }
   else if (sortval < compare) {
      $div = $div.slice(index, $div.length);
   }
   else {
      $div = $div.slice(0, index);
   }
}
while ($div.length > 1);

if (sortval === compare || sortval > compare) { $new.insertBefore($compare); }
else { $new.insertAfter($compare); }

http://jsfiddle.net/ExplosionPIlls/SdjAy/1/

查看更多
劫难
6楼-- · 2019-09-12 12:29

I've solved it like this with help from the answers here:

$("div").each(function(i){
    if(parseFloat($(this).data("weight"))<=weight){
        $(newDiv).insertBefore(this);
        return false;
    }
    else if (i == $(".post").length - 1) {
        $(newDiv).insertAfter(this);
        return false;
    }
});

which seems to work ok and fast enough... anyone sees any flaws in it?

查看更多
登录 后发表回答