Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.
Toon posts:

[JavaScript]Functie met argument in addEvent binnen FOR loop

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hey tweakers,

Een probleempje waar ik niet uit kom. Ik probeer een pagina te maken met 3 tabbladen. Als er op een tabblad geklikt wordt, dan moet de daarbij behorende pagina geladen worden.

Ik heb een array genaamd tabs waarin ik de tabs gestopt heb (h1 nodes). Met een for loop koppel ik aan iedere tab een onclick event om de functie switchTab aan te roepen met de parameter i. Deze parameter komt overeen met het nummer van de tab.


code:
1
2
3
for(i in tabs){
addEvent(tabs[i],"click",function(){switchTab(i)},false);
}


Ik heb echter de indruk dat iedere keer dat deze for-loop rond gegaan word, de anonimous functie overschreven wordt. Want ongeacht welke tab ik aanklik in mijn pagina hij springt altijd naar de laatste pagina/tabblad.

Heeft iemand een suggestie hoe ik dit kan omzeilen? Ik heb al gezocht op got en google, maar kan er niets over vinden.

In mijn tabs array zitten drie elementen, waardoor switchTabs altijd wordt aangeroepen met i =2 :S

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 08:25

Janoz

Moderator Devschuur®

!litemod

De denkfout die je maakt is dat je denkt dat i niet meer veranderd op het moment dat je de functie definieert. Dat klopt niet. De gegenereerde functie heeft gewoon die i er nog in staan. Nadat de hele lus doorlopen is zit in i de laatste tab. Wanneer het event afgevuurd wordt wordt dus switchTab(i) aangeroepen waardoor naar de laatste tab geswitched wordt.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:12

crisp

Devver

Pixelated

En als tabs een array is, waarom itereer je dan met een for-in met het risico dat je ook expando's meeneemt in je iteratie?

Intentionally left blank


Verwijderd

Topicstarter
Klinkt aannemelijk, maar hoe kan ik dit omzeilen.

Ik heb zojuist dit gevonden op:
code:
1
2
3
4
5
6
7
8
for (var i = 0; i < document.links.length; i++) {
    document.links[i].addEventListener('click', (function(n) {
        return function (e) {
            e.preventDefault();
            alert(n);
        };
    })(i), false);
}

Op http://userscripts.org/forums/1/topics/2713

Maar ben er nog niet uit hoe ik dit naar mijn hand kan zetten.

Verwijderd

Topicstarter
@crisp, expando's zegt me niets, wellicht kan je het voor me op helderen.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:12

crisp

Devver

Pixelated

Verwijderd schreef op maandag 21 juli 2008 @ 13:17:
@crisp, expando's zegt me niets, wellicht kan je het voor me op helderen.
JavaScript:
1
2
3
4
5
var a = [0,1,2];
Array.prototype.foo = 'expando';

for (var i in a)
    alert(i + ': ' + a[i]);


;)

Intentionally left blank


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:12

crisp

Devver

Pixelated

En voor wat betreft je probleem: je zal 'i' dus extra moeten scopen:

JavaScript:
1
2
3
4
5
6
7
8
addEvent(tabs[i], 'click', createTabClickHandler(i), false);

// ...

function createTabClickHandler(i)
{
  return function() { switchTab(i); }
}


kijk in elk geval eerst eens of je die 'i' ueberhaupt wel nodig hebt in je switchTab functie, immers is binnen die functie 'this' al een referentie naar je tabs[i] object (mits je een addEvent functie gebruikt die ook in IE de scope behoudt).

Intentionally left blank


Verwijderd

Topicstarter
Hey thnx...


Ik weet niet of ik dit helemaal snap, maar het werkt wel :D

Verwijderd

crisp schreef op maandag 21 juli 2008 @ 13:39:
[...]

JavaScript:
1
2
3
4
5
var a = [0,1,2];
Array.prototype.foo = 'expando';

for (var i in a)
    alert(i + ': ' + a[i]);


;)
Da's dus een reden om het niet te doen. Zeker als je met meerdere mensen aan code werkt, moet je dus niet aan andermans prototypes gaan zitten, en al helemaal niet aan native objecten

Voor Array is het nog wel te doen, aangezien je nog met een teller kan doen (totdat iemand Array.prototype[0] = function(){} ergens in een lib stopt), maar voor een object is het imho van de zotte dat ik bij elke member moet gaan vragen of ik hem er wel zelf in heb gestopt.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:12

crisp

Devver

Pixelated

Verwijderd schreef op maandag 21 juli 2008 @ 14:59:
[...]

Da's dus een reden om het niet te doen. Zeker als je met meerdere mensen aan code werkt, moet je dus niet aan andermans prototypes gaan zitten, en al helemaal niet aan native objecten

Voor Array is het nog wel te doen, aangezien je nog met een teller kan doen (totdat iemand Array.prototype[0] = function(){} ergens in een lib stopt), maar voor een object is het imho van de zotte dat ik bij elke member moet gaan vragen of ik hem er wel zelf in heb gestopt.
Voor Array is het gewoon noodzakelijk als je in oudere browsers ook bepaalde methods wilt kunnen gebruiken ;)

Ik ben het met je eens dat je van Object af moet blijven though.

Het ging mij er om dat je for-in nooit voor een array moet gebruiken omdat, zoals je zelf al aangeeft, je daar gewoon numerieke indexen hebt (en als je dat niet hebt had je een object moeten gebruiken ipv een array) :)

Intentionally left blank

Pagina: 1