如何在循环数组时避免使用eval()?

时间:2017-02-05 21:09:17

标签: javascript

我正在使用Greensock动画库,在构建顺序动画时(有一件事情结束,下一件事就开始了)你必须像这样输入:

childTL.to($box, 1, {x:50,y:0})
       .to($box, 1, {x:50,y:50})
       .to($box, 1, {x:-50,y:50})
       .to($box, 1, {x:-50,y:0});  

我遇到的问题是我将所有内容存储在数据库中或作为变量存储,因此需要使用for循环逐步构建内容。

我想要的是这样的:

var animation = {
  "name": "movearound",
  "sequence": [{
    "duration": "1",
    "vars": {
      "x": "50",
      "y": "0"
    }
  }, {
    "duration": "1",
    "vars": {
      "x": "50",
      "y": "0"
    }
  }, {
    "duration": "1",
    "vars": {
      "x": "50",
      "y": "0"
    }
  }, {
    "duration": "1",
    "vars": {
      "x": "50",
      "y": "0"
    }
  }]
}
target = $(".target123")
childTL = new TimelineLite{onUpdate: updateSlider});

for (S = 0; S < animatelayers.sequence.length; S++) {
  duration = animatelayers.sequence[S]["duration"];
  sequence = animatelayers.sequence[S]["vars"];
  if (S == 0) {

    childTL.to(target, duration, sequence)
  } else {
    .to(".target", duration, sequence);
  }
}

我知道我可以将字符串连接在一起,然后在其上执行eval(),但有没有办法可以不用?

编辑为什么我在谈论eval():

我想我遇到的麻烦是,当涉及到作为字符串与对象的东西时,Greensock是多么挑剔 - 例如你可以在.to()中使用$("#target"),但你不能使用它如果您首先将其定义为变量var target = $("#target");,然后childTL.to(target, 1, {x:50,y:0})将失败,但如果您将其作为var target = "#target",则可以使用。所以在过去我创建它就像Greensock想要的一样,然后使用eval()。虽然我可以继续这样做,但我更愿意寻找更好的方法来完成任务。

1 个答案:

答案 0 :(得分:1)

您的示例代码毫无意义,因此我将演示如何将原始代码段转换为使用数据结构和循环:

childTL.to($box, 1, {x:50,y:0})
       .to($box, 1, {x:50,y:50})
       .to($box, 1, {x:-50,y:50})
       .to($box, 1, {x:-50,y:0});

首先我们定义我们的数据:

var coords = [
    {x: 50, y: 0},
    {x: 50, y:50},
    {x:-50, y:50},
    {x:-50, y: 0}
];

然后我们循环:

var obj = childTL;
for (var i = 0; i < coords.length; i++) {
    obj = obj.to($box, 1, coords[i]);
}

这是对原始链式.to(...).to(...).to(...)调用的严格转换。但是,以这种方式做事实际上并不是必需的。为方便起见,.to方法只返回对象(根据https://greensock.com/docs/#/HTML5/Animation/TimelineLite/to/);你不必使用它。

你可以简单地说:

for (var i = 0; i < coords.length; i++) {
    childTL.to($box, 1, coords[i]);
}