使用CreateJS,我输出了一个包含各种对象实例的画布,以各种方式进行动画制作。几乎所有工作都正常,除了一个问题,我认为是一个范围问题,但我不确定如何修复。我有一个由' _pulsars'引用的实例,包含11个对象的实例' pulsar',代码运行如下:
function attachPulseFuncs() {
var defaultFreq = 0.05; // controls the likelihood of a 'pulse' happening
for (var i = 0; i < _pulsars.children.length; i++) {
var myParent = _pulsars.children[i];
myParent.isPulsing = false;
_myParent.pulse = function() {
if (myParent.isPulsing == false) {
myParent.isPulsing = true;
myParent.__frame = 1
var tween = createjs.Tween.get(myParent).to({__frame:65}, 1500).call(myParent.resetPulse);
tween.addEventListener("change", function() {
myParent.gotoAndStop(myParent.__frame);
});
}
}
myParent.resetPulse = function() {
myParent.gotoAndStop(1);
myParent.isPulsing = false;
}
myParent.callRandomPulse = function() {
var ran = Math.random();
if (ran < freqNumber) {
myParent.pulse();
}
}
createjs.Ticker.addEventListener("tick", myParent.callRandomPulse);
}
}
只会发生最后一个脉冲星的动画(无论群组中有多少个)。我想知道它是否因为只附加了一个事件监听器?或者不知何故,所有的听众都被添加到了一个“脉冲星”中?请帮忙!
编辑:成功! 感谢Robert(以及Bergi与类似问题的链接),我帮助理解了关于闭包和解除传递给函数的变量的更多信息 - 正如另一个线程上的链接所说:
&#34;如果我们传递参数[该]函数使其自己的本地副本 变量(如果它不是通过引用传递的对象类型)&#34;
这允许每个脉冲星对 myParent 的每次迭代所定义的其父脉冲具有离散参考,而不是由的最终值保持的单个外部参考范围参考。 myParent 。 ( @Robert Koritnik 如果我误解了或者这是不正确的,请告诉我!感谢您的帮助,如果我对该网站不那么新,我会+1。很快,希望如此)
答案 0 :(得分:1)
您遇到的问题是,您沿着增加i
的脉冲星进行迭代并添加这些事件侦听器。因此,当你的长子实际开火时,他们会使用myParent
(注意你可能的错字,有时使用前面的下划线,有时候不使用)变量,当你的for循环完成时,最后设置为最后一个脉冲星的变量(最后一个值为{{ 1}});
您必须更改此段代码
i
到此:
myParent.pulse = function() {
if (myParent.isPulsing == false) {
myParent.isPulsing = true;
myParent.__frame = 1
var tween = createjs.Tween.get(myParent).to({__frame:65}, 1500).call(myParent.resetPulse);
tween.addEventListener("change", function() {
myParent.gotoAndStop(myParent.__frame);
});
}
}
这个更改是什么创建了一个新的函数作用域,捕获myParent.pulse = (function(parent) {
return function() {
if (parent.isPulsing === false) {
parent.isPulsing = true;
parent.__frame = 1
var tween = createjs.Tween.get(parent).to({__frame:65}, 1500).call(parent.resetPulse);
tween.addEventListener("change", function() {
parent.gotoAndStop(parent.__frame);
});
}
};
})(myParent);
的当前值并将其存储在局部变量(参数)myParent
中,然后返回一个使用此新捕获值的函数。
也许我已经捕获了太多,我应该只为parent
函数调用创建一个新的函数范围。您应该知道哪个部分需要捕获。我的代码捕获的代码多于可能需要的代码,因此它应该也可以正常工作,但是一段时间后,当您回到它引入一些更改时,它可能会让人感到困惑。
因此,将范围缩小到最小的语句集,如:
tween.addEventListener
但如上所述,这可能无效,因为它使用了最后myParent.pulse = function() {
if (myParent.isPulsing == false) {
myParent.isPulsing = true;
myParent.__frame = 1
var tween = createjs.Tween
.get(myParent)
.to({__frame:65}, 1500)
.call(myParent.resetPulse);
tween.addEventListener("change", (function(parent) {
return function() {
parent.gotoAndStop(parent.__frame);
};
})(myParent));
}
}
个脉冲实例的__frame
变量。所以你最终可能会改变我的代码。