[Javascript] variabelen in for

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • unglaublich
  • Registratie: Augustus 2008
  • Laatst online: 30-03 21:26
Dag mensen,

Het probleem is als volgt. Dit is een stukje uit een script dat een 'pagina-index' maakt met mootools. de variabele 'response.pages' bevat het aantal pagina's. In dit geval drie. 'page' is het huidige paginanummer.

JavaScript:
1
2
3
4
5
6
7
8
for(i=1;i<=response.pages;i++){
  if(i!=page){
    var pagelink = new Element('span', {'class': 'page clicky', 'text': i, 'events': {'click': function(){ getTranslations(i); } }});
  } else {
    var pagelink = new Element('span', {'class': 'active', 'text': i});
  }
  $('translations-pages').adopt(pagelink);
}


Oke, het resultaat hiervan is naar behoren:

HTML:
1
<div id="translations-pages"><span class="active">1</span><span class="page clicky">2</span><span class="page clicky">3</span></div>


Echter wanneer ik de 'click' event aanroep met een linkermuisklik op de span, dan ontvangt de functie getTranslations de variabele 4 i.p.v. respectievelijk 1 2 en 3.

Weet iemand hoe ik dit moet oplossen?

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 16-05 11:46
i wordt pas opgevraagd op het moment dat je creatie-loop afgelopen is. Deze is dan altijd 4. Dit komt door de scope waarin die getTranslations wordt aangeroepen en het feit dat je een referentie naar i meestuurt en niet de inhoud.

Overigens definieer je nu je i-variabele ook als globale variabele. Gebruik bijna altijd "var i" in je for loop.

[ Voor 25% gewijzigd door Bosmonster op 15-06-2010 23:45 ]


Acties:
  • 0 Henk 'm!

  • unglaublich
  • Registratie: Augustus 2008
  • Laatst online: 30-03 21:26
Bosmonster schreef op dinsdag 15 juni 2010 @ 23:40:
i wordt pas opgevraagd op het moment dat je creatie-loop afgelopen is. Deze is dan altijd 4. Dit komt door de scope waarin die getTranslations wordt aangeroepen en het feit dat je een referentie naar i meestuurt en niet de inhoud.

Overigens definieer je nu je i-variabele ook als globale variabele. Gebruik bijna altijd "var i" in je for loop.
Ik snap alleen niet hoe ik aangeef dat ik de inhoud van de variabele 'at the moment' wil meegeven en niet ten tijde van aanroepen. Wat is hier de manier voor?

Acties:
  • 0 Henk 'm!

  • pieturp
  • Registratie: April 2004
  • Laatst online: 10-05 16:33

pieturp

gaffa!

(anonieme) functie er in zetten.

FF googlen op "scope" (en/of "loops") of bovenstaande termen en je komt er wel uit ;)

... en etcetera en zo


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 21:20
Het is jammer dat in JavaScript variabelen per functie-call geactiveerd worden (in plaats van per lexicale scope) wardoor je in dit soort gevallen een extra functie nodig hebt. Een voorbeeldje:
JavaScript:
1
2
3
4
5
6
for (var i = 0; i < 10; ++i) {
    var div = document.createElement('div')
    div.appendChild(document.createTextNode(i))
    div.onclick = function(i) { return function() { alert(i) } } (i)
    document.body.appendChild(div)
}


Maar de meeste callback handlers (in ieder geval de standaard dingen zoals onclick) zetten ook de this pointer naar een relevant element, waar je dan een waarde op kunt definiëren:
JavaScript:
1
2
3
4
5
6
7
for (var i = 0; i < 10; ++i) {
    var div = document.createElement('div')
    div.appendChild(document.createTextNode(i))
    div.onclick = return function() { alert(this.i) }
    div.i = i
    document.body.appendChild(div)
}


Klein voordeel daarvan is dat je ook één enkele functie voor de onclick-handler kunt gebruiken in plaats van steeds een nieuwe closure te maken, aangezien alle parameters niet in de closure zitten maar eigenschappen van het huidige object zijn. (Praktisch gezien is dat voordeel vrij klein overigens.)