2011-07-01 3 views
1

Je suis novice aux objets javascript et j'ai un problème. J'essaye de faire une galerie d'image mais je continue à obtenir une erreur que this.current, this.size & this.initial sont indéfinis, et par conséquent, le manuscrit ne peut pas fonctionner. S'il vous plaît, aidez-moi à résoudre cette erreur. ce qui suit est le script complet.Erreur non définie à l'aide d'objets javascript

function gallery() 
{ 
    this.image = new Array(10); 
    this.initial = 1; 
    this.current = 0; 
    this.size = 10; 
    this.frame_height = 400; 
    this.frame_width = 600; 
    this.initialize=function() 
    { 
     if(document.images) 
     { 
      var count = 1; 
      for(count=1;count<=this.size;count++) 
      { 
       this.image[count] = new Image(); 
       this.image[count].src = 'images/'+count+'.jpg';     
      } 
     } 

    divImg.id = "divImg"; 
    divImg.setAttribute("Width",this.frame_width); 
    divImg.setAttribute("align","center"); 
    divImg.setAttribute("margin","0px auto"); 


    divBtn.id = "divBtn";  
    divBtn.setAttribute("align","center"); 
    divBtn.setAttribute("backgroung-color","Black"); 
    divBtn.setAttribute("color","White"); 
    divBtn.style.margin = "0px auto"; 
    divBtn.className ="btn"; 

    pictureFrame.src = this.image[this.initial].src; 
    pictureFrame.setAttribute('Width',this.frame_width); 
    pictureFrame.setAttribute('Height',this.frame_height); 
    pictureFrame.name = 'img'; 

    btnNext.innerHTML='NEXT'; 
    btnPrevious.innerHTML='PREVIOUS'; 
    btnLast.innerHTML='LAST'; 
    btnFirst.innerHTML='FIRST'; 

    btnFirst.onclick=this.first; 
    btnLast.onclick=this.last; 
    btnPrevious.onclick=this.previous; 
    btnNext.onclick=this.next; 

    myForm.appendChild(pictureFrame); 
    divImg.appendChild(myForm); 

    divBtn.appendChild(btnFirst); 
    divBtn.appendChild(btnPrevious); 
    divBtn.appendChild(btnNext); 
    divBtn.appendChild(btnLast); 

    pageBody.appendChild(divImg); 
    pageBody.appendChild(divBtn); 
    headerTag.appendChild(pageBody); 
} 

this.next=function() 
{ 
    alert(this.size); 
    alert(this.current); 
    if (this.current < this.size) 
    { 
     this.current +=1; 
     pictureFrame.src = this.image[this.current].src; 
    } 
    else 
    { 
     alert("This is the last image"); 
    } 
} 
this.previous=function() 
{ 
    alert(this.current); 
    alert(this.initial); 
    if (this.current > this.initial) 
    { 
     this.current = this.current-1; 
     pictureFrame.src = this.image[this.current].src; 
    } 
    else 
    { 
     alert("This is the first image"); 
    } 

} 
this.first=function() 
{ 
    this.current=this.initial; 
    pictureFrame.src = this.image[this.current].src; 
} 
this.last=function() 
{ 
    alert(this.size); 
    this.current=this.size; 
    pictureFrame.src = this.image[this.current].src; 
} 

}; 

var divImg= document.createElement('div'); 
var divBtn = document.createElement('div'); 
var btnFirst= document.createElement('button'); 
var btnNext= document.createElement('button'); 
var btnPrevious= document.createElement('button'); 
var btnLast= document.createElement('button'); 
var divTop = document.createElement('div'); 
var headerTag = document.getElementsByTagName('html')[0]; 
var pageBody = document.createElement('body'); 
var myForm=document.createElement("form"); 
var pictureFrame = document.createElement('img'); 


var pics=new gallery(); 
window.onload=pics.initialize(); 

Répondre

1

Vous expierencing un hors de portée échec qui est très fréquent pour les personnes qui sont nouveaux ECMAScript.

Chaque fonction possède son propre contexte d'exécution et chaque contexte dans ECMA-/Javascript a sa propre variable de contexte this. Pour éviter cela, la façon la plus courante consiste à stocker une référence à la « externe » this contexte variable dans une variable locale:

function gallery() 
{ 
    this.image = new Array(10); 
    this.initial = 1; 
    this.current = 0; 
    this.size = 10; 
    this.frame_height = 400; 
    this.frame_width = 600; 

    var self = this; 

    //... 

    this.initialize=function() 
    { 
     if(document.images) 
     { 
      var count = 1; 
      for(count=1;count<=self.size;count++) 
      { 
       self.image[count] = new Image(); 
       self.image[count].src = 'images/'+count+'.jpg';     
      } 
     } 
    // ... 

Cela fonctionne dans tous les environnements comme Javascript. En attendant, il existe de «meilleures» (autres) façons d'éviter ce problème dans ECMA. Par exemple, ECMAscript Edition 5 introduit la méthode .bind() qui vous permet de "lier" la référence du this context variable à un objet de votre choix. Beaucoup de frameworks javascript offrent une façon assez similaire de lier this à un objet, même Javascript vous permet de le faire avec un petit effort.

1

Ce qui Jandy dit est exact, lorsque l'objet window appelle pics.initialise, this fait référence à window (this fait référence à l'appelant de la fonction, à moins que la fonction est anonyme).

Cependant, il y a une solution plus simple que vous préférez:

Au lieu de

var pics = new gallery(); 
window.onload = pics.initialize; 

Vous pouvez faire:

var pics = new gallery(); 
window.onload = function() { 
    pics.initialize(); 
}; 

Parce qu'il est enveloppé dans une fonction anonyme, this sera reportez-vous à l'instance gallery au lieu de window. Les suggestions d'Andrew sont certainement plus robustes, mais peuvent être un peu difficiles pour quelqu'un qui est encore aux prises avec Javascript.