2009-06-02 9 views
0

다른 요소에 대해 함수가 여러 번 호출되는 문제가 있습니다. 이 함수를 여러 요소에 대해 사용할 수 있도록 모든 변수를 지역화해야한다고 생각합니다. 그것이 중요한 경우에는 jquery 1.3을 호출합니다.자바 스크립트 지원

한 번만 pageSlide를 호출하면 모든 것이 정상이지만 한 번 여러 번 호출하면 고통 스럽습니다. 오류가 없으며 엉뚱한 행동입니다.

코드는

var slideMenu=function(){ 
    var speed, startWidth, time, menuId, liID, menuLen, menuWidth, globalWidth, openWidth; 
    return{ 

    speed : 0, startWidth : 0, time : 0, menuId : 0, liID : 0, menuLen : 0,  menuWidth : 0, globalWidth : 0, openWidth : 0, 

    build:function(ulID,passStartWidth,passTime,s,passSlideLen,passHeight){ 
     speed=s; 
     startWidth=passStartWidth; 
     time=passTime; 
     menuId=document.getElementById(ulID); 
     liID=menuId.getElementsByTagName('li'); 
     menuLen=liID.length; 
     menuWidth=menuId.offsetWidth; 
     globalWidth=menuWidth/menuLen; 
     openWidth=Math.floor((menuWidth-startWidth)/(menuLen-1)); 
     var i=0; 
     for(i;i<menuLen;i++){ 
     s=liID[i]; 
     s.style.width=globalWidth+'px'; 
     this.timer(s) 
     } 
     if(passSlideLen!=null){ 
     menuId.timer=setInterval(function(){ 
      slideMenu.slide(liID[passSlideLen-1]) 
     },time) 
     } 
    }, 
    timer:function(s){ 
     s.onmouseover=function(){ 
     clearInterval(menuId.htimer); 
     clearInterval(menuId.timer); 
     menuId.timer=setInterval(function(){ 
      slideMenu.slide(s) 
     }, 
     time) 
     } 
     s.onmouseout=function(){ 
     clearInterval(menuId.timer); 
     clearInterval(menuId.htimer); 
     menuId.htimer=setInterval(function(){ 
      slideMenu.slide(s,true) 
     }, 
     time) 
     } 
    }, 
    slide:function(s,passChange){ 
     var changeWidth=parseInt(s.style.width); 
     if((changeWidth<startWidth && !passChange) || (changeWidth>globalWidth && passChange)){ 
     var overallWidth=0; 
     var i=0; 
     for(i;i<menuLen;i++){ 
      if(liID[i]!=s){ 
      var slideObj,openWidth; var opening=0; slideObj=liID[i]; openWidth=parseInt(slideObj.style.width); 
      if(openWidth<globalWidth && passChange){ 
       opening=Math.floor((globalWidth-openWidth)/speed); 
       opening=(opening>0)?opening:1; 
       slideObj.style.width=(openWidth+opening)+'px'; 
      }else if(openWidth>openWidth && !passChange){ 
       opening=Math.floor((openWidth-openWidth)/speed); 
       opening=(opening>0)?opening:1; 
       slideObj.style.width=(openWidth-opening)+'px' 
      } 
      if(passChange){ 
       overallWidth=overallWidth+(openWidth+opening)}else{overallWidth=overallWidth+(openWidth-opening) 
      } 
      } 
     } 
     s.style.width=(menuWidth-overallWidth)+'px'; 
     }else{ 
     clearInterval(menuId.timer); 
     clearInterval(menuId.htimer) 
     } 
    } 
    }; 
}(); 

위의 코드는 오류가 있지만 작동하지 않는 업데이트되었습니다. 이 키워드를 사용하면 더 좋아지지 않습니다.

제 질문은 어떤 변수가 "this"가되어야한다는 것입니다. 나는 여러 가지 조합을 시도해 봤지만 뭔가 빠졌습니다.

+1

이 코드가 무엇을하는지 정확하게 설명하는 것이 도움이 될 것입니다. – cgp

+4

변수 이름이 빠르다면, 지금은 매우 고통 스럽습니다. – mkoryak

+2

난독 화되지 않은 버전은 읽기가 더 쉬울 것입니다. – fmsf

답변

2

나는, 당신은 모듈 패턴의 전체 개념을 오해 것 같아요 return 문 앞에.

이러한 변수를 변경할 때마다 모든 인스턴스가 변경의 영향을 받는다고 가정합니다. 당신이, 당신이 당신의 함수에 의해 반환 된 객체로 변수를 넣어 가지고있는 글로벌 범위에서 변수 안전을 유지하려면 다른 한편으로

var slideMenu=function(){ 
    // Declare or initialize your private static variables here  
    var speed, startWidth, time; 

    return { 
     // Public part of your object 
     slide:function(s,passChange){ 
      //To access your variable   
      speed = 20; 
     ... 

,이 인스턴스 속성을 당 고유 제공하는 신뢰할 수있는 방법입니다 .

때때로 내부/공용 속성 사이에 몇몇 사람을 구별 할 수 있도록하기 위해 결론

var slideMenu=function(){ 
    // Declare or initialize your private static variables here  
    var speed, startWidth, time; 

    return { 
     // Public part of your object 
     // Declare internal or public properties here 
     menuId : 0, 
     liID : 0, 
     menuLen : 0, 
     ... 
     slide:function(s,passChange){ 
      //To access your private static variable inside functions   
      speed = 20; 
      // To access your public/internal properties 
      this.menuId = s; // for example ;) 
     } 

는 선도가 (속성은 여전히 ​​외부에서 계속 액세스 할 수 있습니다) 내부 특성에 밑줄 씁니다.

희망, 행운을 빕니다!

+0

그것은 도움이되었습니다. 고맙습니다!! – user44585

1

개체에 개인 정적 변수를 저장할 수있는 모듈 패턴을 사용하고 있으므로이 동작이 발생합니다. 문제는 이러한 변수가 모든 인스턴스간에 공유된다는 것입니다.

var sp=0; 
    var st=0; 
    var t=0; 
    var m=''; 
    var sa=''; 
    var l=0; 
    var w=0; 
    var gw=0; 
    var ot=0; 

당신은 스크립트의 반환 일부 또는 생성자에서 일명 공개 인스턴스로 이러한 변수를 이동해야합니다 (그러나이 경우에는 모든 변수에 대한 게터를 제공해야합니다). 당신이 다음 방금 선언하거나 키워드 "VAR"로 변수를 초기화 할 수있는 모든 인스턴스간에 공유 전역 정적 변수를 가질 필요가있을 때

return{ 

    // Place your variables here 
    sp : 0, 
    st : 0, 

    ... 

    build:function(sm,sw,mt,s,sl,h){ 
     // And then use the this keyword to access the variable 
     this.sp=s; 
     this.st=sw; 
     t=mt; 
     m=document.getElementById(sm); 
     sa=m.getElementsByTagName('li'); 
     l=sa.length;  
     w=m.offsetWidth;  
     gw=w/l; 
     ... 
+0

좋은 답변입니다. 그래도 변수에 액세스하려면 "this"를 사용해야합니까? "sp = s;"라고 쓰면 어떻게됩니까? –

+0

동일한 이름을 가진 개인 정적 변수가 생성자에 존재하거나 같은 이름의 동일한 범위 (로컬 변수)에있는 경우에만 작동합니다. 인스턴스 당 변수의 고유성을 보장하려면 "this"키워드를 사용해야합니다. –

+0

this.w = this.w/this.l까지는 this.sp = s의 줄에 this 키워드를 사용하겠습니까? 그 값 중 많은 수가 전역 적이기 때문입니다. 그러면 gw = w/l이 this.gw = this.w/this.l이됩니까? 는 당신의 도움을 주셔서 감사합니다. – user44585