gpt4 book ai didi

Javascript 递归调用会产生范围错误

转载 作者:行者123 更新时间:2023-12-03 03:03:25 24 4
gpt4 key购买 nike

我试图让以下脚本正常工作,但是当它落入 continueAnimation 函数时,它不会更新 cPreloaderTimeout 变量,并且会以“未捕获的 RangeError:超出最大调用堆栈大小”的状态运行。

    var loadingIcon = {

cSpeed : 8,
cWidth : 64,
cHeight : 32,
cTotalFrames : 7,
cFrameWidth : 64,
cImageSrc : 'sprites.png',

cImageTimeout : false,
cIndex : 0,
cXpos : 0,
cPreloaderTimeout : false,
SECONDS_BETWEEN_FRAMES : 0,

startAnimation : function() {
document.getElementById('loaderImage').style.backgroundImage='url('+ this.cImageSrc+')';
document.getElementById('loaderImage').style.width=this.cWidth+'px';
document.getElementById('loaderImage').style.height=this.cHeight+'px';

//FPS = Math.round(100/(maxSpeed+2-speed));
FPS = Math.round(100/this.cSpeed);
SECONDS_BETWEEN_FRAMES = 1 / FPS;

this.cPreloaderTimeout = setTimeout( this.continueAnimation(), SECONDS_BETWEEN_FRAMES/1000);

},

continueAnimation : function() {
this.cXpos += this.cFrameWidth;
//increase the index so we know which frame of our animation we are currently on
this.cIndex += 1;

//if our cIndex is higher than our total number of frames, we're at the end and should restart
if (this.cIndex >= this.cTotalFrames) {
this.cXpos =0;
this.cIndex=0;
}

if(document.getElementById('loaderImage'))
document.getElementById('loaderImage').style.backgroundPosition=(-this.cXpos)+'px 0';


this.cPreloaderTimeout = setTimeout(this.continueAnimation(), SECONDS_BETWEEN_FRAMES*1000);
},

stopAnimation : function(){//stops animation
clearTimeout( this.cPreloaderTimeout );
this.cPreloaderTimeout = false;
}

}

jQuery( document ).ready(function() {

jQuery( document ).on("click", "#test", function(){

var loader = loadingIcon;

loader.startAnimation();

setTimeout( loader.stopAnimation(), 3000);

});
});

起初它是一个简单的 JavaScript 脚本,但我试图从中创建一个对象,以便它可以重复使用并同时多次使用。现在的问题是,当触发 startAnimation 或 continueAnimation 时,cPreloaderTimeout 变量未正确设置。

最佳答案

您有几个问题。

首先,您的 cPreloaderTimeout 不会像您想象的那样设置,因为您没有创建带有原型(prototype)的对象,因此该函数内 this 的范围将是是函数本身,而不是对象。

其次,setTimeout 接受一个函数,但是当您尝试使用它时,您正在调用该函数,因此发送到 setTimeout 的值将是函数的结果,而不是函数本身。

考虑格式:

function LoadIcon() {
this.cSpeed = 8;
// All your other properties
}

LoadIcon.prototype.startAnimation = function() {
// your startAnimation function, concluding with
this.preloaderTimeout = setTimeout(this.continueAnimation.bind(this), SECONDS_BETWEEN_FRAMES/1000);
}

// the rest of the methods built the same way

//then, your calling code would look like:

var loadIcon = new LoadIcon();
loadIcon.startAnimation();

编辑我更新了 setTimeout 调用,因为我忘记了绑定(bind)到 this 以便在回调触发时正确确定作用域。

关于Javascript 递归调用会产生范围错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47274659/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com