0

I have a list of elements in my page that I want to apply a jQuery sliding animation to. But, I'd like it so that the animations are chained in order, i.e., an element will start its animation only when the previous one's animation has finished.

The list's length is variable, and so I need to find a dynamic solution. I came up with this:

function closeYear(year, speed, complete) {
  $(year).next().slideUp(speed, complete);
}

function closeYears(years, speed, complete) {
  if ($(years).length == 1) {
    closeYear($(years).first(), speed, complete);
  } else if ($(years).length > 1) {
    var codeStr = ""
    $(years).slice(0, $(years).length - 1).each(function(k) {
      codeStr = codeStr + "closeYear($(years)[" + k + "],'" + speed + "',";
    });
    codeStr = codeStr + "closeYear($(years).last(),'" + speed + "',complete)" + Array($(years).length).join(")") + ";";

    eval(codeStr);
  }
}

With the above code, I am able to accomplish what I want, including being able to specify the speed of the animations, as well as a complete function to be executed when everything has been processed, like so:

closeYears($(".year"), "slow", function() {console.log("done!");})

My question is regarding the use of the eval() function. And because I am not very savvy with regards to security issues, I am wondering if there is anything to be worried about in my code, the way it is written, or if there is a better/safer/smarter way to do what I want...

Any comments?

Vasco
  • 361
  • 3
  • 11

1 Answers1

1

You probably just need a pseudo recursive function:

function closeYears(years, speed, complete) {
  (function close(i){
     if(!years[i])  return complete();
     closeYear(years[i],speed,function(){
        close(i+1);        
      } );
 })(0);
}
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • Works beautifully. I had tried something similar before but I must have been doing something wrong somewhere. Thank you very much @Jonas w – Vasco Jul 21 '17 at 16:53