João Silva João Silva - 1 month ago 10
jQuery Question

How to animate an array of array with jquery

I have a border 9x9, with lines, columns and squares, like a sudoku border and I want to animate it but I had a few problems when there was multiple animations at same time, so I decided to animate one array of elements each time, for that I putted them in an array and want to animate it one by one but I'm having some issues.
There is a piece of my code:

var col,
row,
square,
arr = [];

col = checkColumn(cell);
row = checkRow(cell);
square = checkSquare(cell);

if(row != null){
arr.push(row);
}

if(col != null){
arr.push(col);
}

if(square != null){
arr.push(square)
}

if(arr.length !=0){
arr.each(function(){
enlight($(this));
});
}


So, at the moment I can't use arr.each because it says arr isnt a function, If I change arr to:

arr ={}


I can't use .push to add the elements, is there an solution to animate them one by one?
Thank you in advance for the help!

The enlight does this:

function enlight(cells){
var delayTime=0;
cells.each(function(){
$(this).parent().delay(delayTime).animate({
"background-color" : "#ffa500"

}, 500).delay(100)
.animate({
"background-color" : "#ffffff"
});
delayTime+=100;
})

}


So, I want to sent an array each time (row, col and square) to animate one by one not all at same time.

Some HTML:

<div class="board">
<div class="row">
<div class="cell">
<input type="number" data-column="0" data-line="0">
</div>
<div class="cell">
<input type="number" data-column="1" data-line="0">
</div>
<div class="cell">
<input type="number" data-column="2" data-line="0">
</div>
<div class="cell">
<input type="number" data-column="3" data-line="0">
</div>
(more cells 81 in total)

Answer

so I decided to animate one array of elements each time, for that I putted them in an array and want to animate it one by one

You can use .queue(), .promise(), .then(), $.map() to animate elements in sequential order.

// set queue name for `.row` element to `"enlighten"` iterate `.row` elements
$({}).queue("enlighten", $.map($(".row"), function(el, index) {
  // return a function to push to `"enlighten"` queue
  return function(next) {
    // set queue name for `.cell input` elements to `"cells"`
    // iterate `input` elements within `.cell` elements
    $({}).queue("cells", $.map($(".cell > input", el), function(cell) {
      // return a function to push to `"cells"` queue
      return function(_next) {
        // animate `.cell input` elements
        $(cell).delay(100).animate({
            "background-color" : "#ffa500"
        }, 500).delay(100) 
        .animate({
          "background-color" : "#ffffff"
        })
        // when current `.cell input` element animation completes
        // call `_next` function in `"cells"` queue
        .promise().then(_next)           
      }
    // call first function in `"cells"` queue
    // when all `"cells"` queue functions have been called
    // call `next` function in `"enlighten"` queue
    })).dequeue("cells").promise("cells").then(next)
  }
// call first function in `"enlighten"` queue
})).dequeue("enlighten").promise("enlighten")
// do stuff when all functions in `"enlighten"` and `"cells"`
// queues have been called
.then(function() {
  console.log("all animations complete")
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script   src="http://code.jquery.com/ui/1.12.1/jquery-ui.min.js"   integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="   crossorigin="anonymous"></script>
first board
<div class="board">
  first row
  <div class="row">
    <div class="cell">
      <input type="number" data-column="0" data-line="0">
    </div>
    <div class="cell">
      <input type="number" data-column="1" data-line="0">
    </div>
    <div class="cell">
      <input type="number" data-column="2" data-line="0">
    </div>
    <div class="cell">
      <input type="number" data-column="3" data-line="0">
    </div>
  </div>
</div>
<br>
second board
<div class="board">
  second row
  <div class="row">
    <div class="cell">
      <input type="number" data-column="0" data-line="0">
    </div>
    <div class="cell">
      <input type="number" data-column="1" data-line="0">
    </div>
    <div class="cell">
      <input type="number" data-column="2" data-line="0">
    </div>
    <div class="cell">
      <input type="number" data-column="3" data-line="0">
    </div>
  </div>
</div>