2010-02-25 3 views
10

Javascript 객체를 작성하고 setTimeout을 사용하여 해당 객체에서 메서드를 호출하는 데 문제가 있습니다. 다양한 해결 방법을 시도했지만 항상 루프의 두 번째 부분에서 범위가 내 사용자 지정 개체가 아닌 창 개체가됩니다. 경고 : 저는 자바 스크립트에서 꽤 새로 왔습니다.setTimeout을 사용하는 메서드가 범위를 잃습니다.

내 코드 :

내 방법을 통해 개체에 대한 참조를 전달하려고 시도 할 수 있지만, 심지어는 작동하지 않도록 내 최신 시도가 도우미 함수 triggerSlide를 구축했다
$(function() { 
slide1 = Object.create(slideItem); 
slide1.setDivs($('#SpotSlideArea')); 
slide1.loc = 'getSpot'; 
slide2 = Object.create(slideItem); 
slide2.setDivs($('#ProgSlideArea')); 
slide2.loc = 'getProg'; 
slide2.slide = 1; 
setTimeout('triggerSlide(slide1)', slide1.wait); 
setTimeout('triggerSlide(slide2)', slide2.wait); 
}); 

function triggerSlide(slideObject) { 
slideObject.changeSlide(slideObject); 
} 

var slideItem = { 
div1: null, 
div2: null, 
slide: 0, 
wait: 15000, 
time: 1500, 
loc: null, 
changeSlide: function(self) { 
    this.slide ? curDiv = this.div1:curDiv = this.div2; 
    $(curDiv).load(location.pathname + "/" + this.loc, this.slideGo(self)); 
}, 
setDivs: function(div) { 
    var subDivs = $(div).children(); 
    this.div1 = subDivs[0]; 
    this.div2 = subDivs[1]; 
}, 
slideGo: function(self) { 
    if(this.slide) { 
    $(this.div2).animate({ 
    marginLeft: "-300px" 
    }, this.time); 
    $(this.div1).animate({ 
    marginLeft: "0" 
    }, this.time); 
    setTimeout('triggerSlide(self)', this.wait); 
    } else {  
    $(this.div1).animate({ 
    marginLeft: "300px" 
    }, this.time); 
    $(this.div2).animate({ 
    marginLeft: "0" 
    }, this.time); 
    setTimeout('triggerSlide(self)', this.wait); 
    } 
    this.slide ? this.slide=0:this.slide=1; 
} 
} 

.

나는 setInterval을 사용할 수 있으며 그러나, 작동 : 타이머가 나는 문제를 해결하는 방법을 얻는 방법을 배울 수 없습니다

  • 다시 시작하기 전에

    1. 나는 완료 애니메이션을 보장합니다. :)
  • 답변

    15

    언어를 시작하고 (Stackoverflow를 사용하여) 자바 프로그래머에게 꼭 읽어야합니다.

    Java와 달리 선언 된 방식에 관계없이 모든 개체에 함수의 "바인딩"이 없습니다. 객체 컨텍스트의 바인딩은 함수 호출시에만 발생합니다. 따라서 함수에 대한 참조를 "setTimeout"과 같은 것으로 전달하면 어떤 객체에서 함수를 얻은 것이 전혀 중요하지 않습니다. 이것은 단지 함수이고 "setTimeout"은 기본 컨텍스트 — window 개체로 호출합니다.

    이 문제를 해결할 수있는 방법은 여러 가지가 있습니다. (나는 그것을 "문제"라고 부르지 않으며 언어의 사실이며 매우 강력합니다.) 어떤 종류의 프레임 워크를 사용했다면 더 쉬울 것입니다.

    또 다른 한 가지는 : 코드가 포함 된 문자열로 시간 제한 및 간격 처리기를 바인딩하는 것입니다. 이것은 꽤 못생긴 관행입니다. 따라서 함수 표현식을 만드는 데 익숙해 져야합니다. — 즉, 값이 함수 인 표현식을 작성해야합니다. 당신의 "slideItem"핸들러를 들어

    , 예를 들어, 당신은이 작업을 수행 할 수 있습니다

    // ... 
    setTimeout(function() { slideItem.changeSlide(); }, 5000); 
    

    그런 식으로, 항상 같은 "slideItem"객체 "changeSlide"를 호출하는 시간 제한 메커니즘에 의해 호출 기능을 문맥. "this"가 올바른 객체를 가리 키기 때문에 "changeSlide"에 "self"매개 변수가 필요하지 않습니다.

    [편집] 실제로 당신이 jQuery를 사용하고 있다는 것을 알았습니다. 이것은 좋은 것입니다.

    +0

    문자열에서 +1 코드는 절대적으로 필요하지 않는 한 일반적으로 피해야합니다. 여기에는'new function ('some code');,'setTimeout ("doSomething()", 0); 그리고 모두가 좋아하는'eval ('some code');가 포함됩니다. 첫 번째 두 가지는 필자에게 * 절대 * JSON 및 입력 수학 표현에 대한 필요성을 보지 못했습니다 :-) –

    +0

    위의 시도한 및 초기 호출에 대해 작동하지만 호출 작업을 반복합니다 (slideGo()의 setTimeout() 호출은 여전히 ​​작동하지 않습니다. 위와 같이 포맷했지만 위의 slideItem 대신이 형식을 사용합니다. 즉 setTimeout (function() {this.changeSlide();}, this.wait); Firebug에서 this.changeSlide()가 함수가 아닙니다. slideGo 메서드에서 'this'가 내 slideItem을 참조하고 있지만 두 번째 setTimeout 호출이 발생할 때 나타나지 않습니다. –

    +0

    나는 slide.Go 메서드의 시작 부분에 this = this를 추가하려고했음을 언급해야합니다. 그러나 메서드 내에서만이 아니라 전역 범위에 추가되는 것처럼 보입니다. 페이지를 만들면 그것들은 각 setTimeout에 의해 트리거되어 움직입니다. –

    0

    이 코드는 지금 테스트 할 수 없지만 도움이됩니까?

    setTimeout(function(){triggerSlide(slide1)}, slide1.wait); 
    
    +0

    Ugg. 왜 그것을 문자열로 전달합니까? – Pointy

    +0

    반대로? 함수 이름 지정? – lance

    +0

    예, 함수 이름 또는 익명 함수를 지정합니다. 귀하의 예를 들어, 따옴표를 모두 제거하는 것이 좋습니다.그러나 그의 메커니즘은 어쨌든 불필요하게 복잡하고 실제로 다르게 수행되어야합니다. – Pointy

    0

    이것은 jQuery입니다. 맞습니까? 콜백 매개 변수는 animate()입니다. 애니메이션이 완료된 후에 호출 할 함수에 전달하면 jQuery가 호출을 처리합니다. 콜백은 원하는 범위를 잘 캡처해야합니다.

    관련 문제