How to show HTML elements sorted by animation

Here is my snippet:

.item {
  display:inline-block;
  width:120px;
  height:120px;
  border:1px solid red;
}
      

<div id="listing">
  <div data-value="5" class="item">item 5</div>
  <div data-value="3" class="item">item 3</div>
  <div data-value="2" class="item">item 2</div>
  <div data-value="1" class="item">item 1</div>
  <div data-value="4" class="item">item 4</div>
</div>
      

Run codeHide result


I would like to sort div

based on the value of an attribute data-value

, but I want to show that the elements are rearranged using animation. How can i do this?

+3


source to share


2 answers


You can animate the sort here:

  • Scroll through all the elements and save their positions.
  • Place the elements absolutely in their original position.
  • Get the position of the element to be replaced and animate that position.
  • (Optional) After the animation finishes, you can swap absolutely positioned elements with ordered positions so the order of the DOM elements is correct.


function animateSort(parent, child, sortAttribute) {
  var promises = [];
  var positions = [];
  var originals = $(parent).find(child);
  var sorted = originals.toArray().sort(function(a, b) {
    return $(a).attr(sortAttribute) > $(b).attr(sortAttribute);
  });

  originals.each(function() {
    //store original positions
    positions.push($(this).position());
  }).each(function(originalIndex) {
    //change items to absolute position
    var $this = $(this);
    var newIndex = sorted.indexOf(this);
    sorted[newIndex] = $this.clone(); //copy the original item before messing with its positioning
    $this.css("position", "absolute").css("top", positions[originalIndex].top + "px").css("left", positions[originalIndex].left + "px");

    //animate to the new position
    var promise = $this.animate({
      top: positions[newIndex].top + "px",
      left: positions[newIndex].left + "px"
    }, 1000);
    promises.push(promise);
  });

  //instead of leaving the items out-of-order and positioned, replace them in sorted order
  $.when.apply($, promises).done(function() {
    originals.each(function(index) {
      $(this).replaceWith(sorted[index]);
    });
  });
}

$(function() {
  $("input").click(function() {
    animateSort("#listing", "div", "data-value");
  });
});
      

.item {
  display: inline-block;
  width: 120px;
  height: 120px;
  border: 1px solid red;
}
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="button" value="Sort" />
<div id="listing">
  <div data-value="5" class="item">item 5</div>
  <div data-value="3" class="item">item 3</div>
  <div data-value="2" class="item">item 2</div>
  <div data-value="1" class="item">item 1</div>
  <div data-value="4" class="item">item 4</div>
</div>
      

Run codeHide result


+5


source


While you can easily do this without jquery, here is a (non-animated) way to sort them:

var sorted = $('#listing div').sort(function(a,b) {
   return $(a).data('value') - $(b).data('value');
});

$('#listing').html(sorted);

      



https://jsfiddle.net/yne89aw4/

I'll see what I can do to animate the sort

+1


source







All Articles