2017-11-13 4 views
0

다음 스크립트를 작동 시키려고합니다.하지만 continueAnimation 함수에 포함될 때 cPreloaderTimeout 변수가 업데이트되지 않고 'Uncaught RangeError : Maximum call stack size 초과했습니다 '. 자바 재귀 호출이 범위 오류를 만듭니다

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); 

    }); 
}); 

은 처음에는 일반 자바 스크립트,하지만 나는 그것이 동시에 재사용 여러 번 할 수 있도록에서 개체를 만들기 위해 노력하고있어. 이제 문제는 startAnimation 또는 continueAnimation이 트리거 될 때 cPreloaderTimeout 변수가 올바르게 설정되지 않았기 때문입니다.

+1

'setTimeout'을 올바르게 사용하지 않았기 때문에. 'setTimeout (this.continueAnimation(), ...)'에서'()'을 제거하고'setTimeout'에 대해 더 읽으십시오. –

+1

**주의 : **'setTimeout' 문제를 고칠 때, 당신은 [**'이 이슈 **]에 빠지게 될 것입니다. (https://stackoverflow.com/questions/591269/settimeout-and-this - 자바 스크립트). –

답변

1

몇 가지 문제가 있습니다.

우선 프로토 타입이있는 객체를 만들지 않으므로 cPreloaderTimeout이 생각대로 설정되지 않으므로 해당 함수 안에 this의 범위가 함수 자체가 될 것입니다. 그 물체.

두 번째로 setTimeout은 함수를 취하지 만 사용하려고하면 함수를 호출하므로 setTimeout에 전송 된 값은 함수 자체가 아니라 함수의 결과가됩니다.

대신 형식을 고려 : 내가 올바른 범위 지정 콜백 화재에 대한 this 바인딩에 대해 잊었다 나는이 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(); 

편집 할 수 있습니다.

+0

나는 그 형식을 이미 시도했지만, continueAnimation에서 LoadIcon 대신에 'this'를 사용할 수 없다. 그 창 –

+0

@MartijnBastiaansen, 미안. 그 문제는 이제 고쳐졌고 또 다른 모습을 보입니다. – Paul

+0

이제 완벽하게 작동합니다. 감사합니다. :) –