Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[JS] Referentie naar object in for loop

Pagina: 1
Acties:

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 24-11 23:24
Ik heb de volgende code;

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    function createHeader(dataRow)
    {
        thead = document.createElement("THEAD");
        headrow = document.createElement("TR");
        thead.appendChild(headrow);
        for (var g = 0; g < dataRow.length; g++)
        {
            th = document.createElement("TH");
            th.appendChild(document.createTextNode(dataRow[g]));
            th.onclick = function()
            {
                sortCol(th);
            }
            headrow.appendChild(th);
        }
        return thead;
    }


Ik merk dat als ik op een van de TH's klik ik altijd de inhoud van de laatste meestuur. 'self' gaat natuurlijk niet werken, omdat dat niet de scope is. Dus eigenlijk wil ik dat hij de referentie naar die TH houdt, en niet steeds bij iedere stap naar een nieuwe gaat refereren wat betreft de aanroep van de functie sortCol().

iOS developer


Verwijderd

code:
1
2
3
th.onclick = function()  {
  sortCol(this);
}
2 letters meer ;)

on de onclick handler refereert "this" naar het object wat die method aanroept. In dat geval is het die th

[ Voor 14% gewijzigd door Verwijderd op 26-11-2007 09:29 ]


  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 24-11 23:24
Hey, waarom werkte dat de eerste keer niet toen ik dat probeerde? :?

Bedankt!

iOS developer


Verwijderd

Tja, zo zit javascript in elkaar, is een eigenaardige eigenschap van de taal. Eerste keer werkt het nooit ;)

Verwijderd

BikkelZ schreef op maandag 26 november 2007 @ 09:39:
Hey, waarom werkte dat de eerste keer niet toen ik dat probeerde? :?

Bedankt!
Eens ff kijken of ik dat correct kan uitleggen:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    function createHeader(dataRow)
    {
        // dit is een function, die creeert z'n eigen scope voor
        // alle locale variabelen

        thead = document.createElement("THEAD");
        headrow = document.createElement("TR");
        thead.appendChild(headrow);
        for (var g = 0; g < dataRow.length; g++)
        {
            // een for-loop creeert geen nieuwe, eigen scope maar gebruikt
            // dezelfde variabelen als de function

            th = document.createElement("TH");
            th.appendChild(document.createTextNode(dataRow[g]));
            th.onclick = function()
            {
                // dit is ook een function met z'n eigen scope maar je gebruikt
                // een variabele uit een scope 'hoger': th
                // deze variabele krijgt (door de for-loop) steeds een andere waarde
                // en omdat het een onclick event handler is betekent dat dat tegen
                // de tijd dat deze functie wordt uitgevoerd, de for-loop is voltooid en
                // de variabele th verwijst naar de laatste waarde uit de for-loop

                sortCol(th);

                // omdat deze functie een event-handler is van het TH DOM element
                // kun je hier het keyword this gebruiken om naar dat element te verwijzen
                // en heb je de variabele th niet nodig
            }
            headrow.appendChild(th);
        }
        return thead;
    }

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 24-11 23:24
Verwijderd schreef op maandag 26 november 2007 @ 09:57:
Tja, zo zit javascript in elkaar, is een eigenaardige eigenschap van de taal. Eerste keer werkt het nooit ;)
Ik dacht dat 'net als je dacht dat je het snapte werkt het toch niet'. Of was dat alleen in 1.5? ;)

iOS developer


  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 24-11 23:24
Weer een zelfde probleem volgens mij:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
        for (var u = 0; u < treeData[parentLevel+1][parentNode].length; u++)
        {
            var thistd;
            
            if (bodytrs[u] == undefined)
            {
                thistr = document.createElement("TR");
                for (var n = 0; n < parentLevel + 2; n++)
                {
                    newtd = document.createElement("TD");
                    thistr.appendChild(newtd);
                }
                thistd = newtd;
                tbody.appendChild(thistr);
            }
            else
            {
                thistr = bodytrs[u];
                thistd = document.createElement("TD");
                thistr.appendChild(thistd);
            }
            thistd.appendChild(document.createTextNode(treeData[parentLevel+1][parentNode][u][1]));
            thistd.onclick = function()
            {
                nextLevel(treeData[parentLevel][parentNode][u][0], 0+parentLevel+1);
            }
        }


Het gaat om het laatste stuk. Er wordt een stuk van een array toegekend, en die array daar loop ik vervolgens nog verder doorheen. Is er een manier om er voor te zorgen dat de data gekopieerd wordt in plaats van een referentie gebruikt wordt?

[ Voor 5% gewijzigd door BikkelZ op 29-11-2007 10:59 ]

iOS developer


Verwijderd

een array kopieren doe je met
JavaScript:
1
var copy = Array.slice(0);

maar het is me verder niet duidelijk wat je nou wilt of wat je probleem is.

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 24-11 23:24
Ja, maar dan zou copy iedere keer aangepast worden in die loop, en dan heb ik alsnog het zelfde probleem.
Verwijderd schreef op donderdag 29 november 2007 @ 12:49:
een array kopieren doe je met
JavaScript:
1
var copy = Array.slice(0);

maar het is me verder niet duidelijk wat je nou wilt of wat je probleem is.
Het probleem is dat de variabelen bij het doorlopen van die loop blijven updaten bij de functie. Dus u blijft oplopen tot het einde, zodat ik steeds met de laatste waarde zit in plaats van de waarde op het moment waar hij zit in de loop als ik die functie toeken.

Zo lang ik harde waardes mee geef, ze zelf in klop dan werken de functies. Anders wordt steeds onder iedere TD die functie met dezelfde parameters aangeroepen.

[ Voor 7% gewijzigd door BikkelZ op 29-11-2007 12:59 ]

iOS developer


Verwijderd

ow wacht, nu snap ik m
JavaScript:
1
2
3
4
5
thistd.onclick = function(v) {
  return function() {
    nextLevel(treeData[parentLevel][parentNode][v][0], 0+parentLevel+1);
  };
}(u);


je maakt dus een nieuwe scope aan en stopt daar je variabele in. v mag ook u heten, maar dat maakt het ietwat minder helder

[ Voor 41% gewijzigd door Verwijderd op 29-11-2007 13:33 ]


  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 24-11 23:24
Ik heb het verbouwd naar:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
            tempVar = treeData[parentLevel+1][parentNode][u][0];
// dit is de data die bij die td hoort
            if (treeData[parentLevel+2][tempVar] != undefined)
// soms heeft die data geen childnodes, dan wil ik ook geen nextLevel doen
            {
                thistd.onclick = function(tempVar)
// en dit is een mouseclick event als ik hem alert?
                {
                    return function()
                    {
                        nextLevel(tempVar, parentLevel+1);
                        showInfo(tempVar);
                    }
                }
            }


En nu gebeurt er helemaal niets meer.

[ Voor 4% gewijzigd door BikkelZ op 29-11-2007 13:15 ]

iOS developer


Verwijderd

je leest ook niet goed :)
ik voer de eerste functie op het einde uit. Die geef ik als parameter "u" mee. Binnen de functie heet die parameter "v", want zo is de functie gedeclareerd. "v" bestaat dus alleen binnen de scope van die ene functie. Die eerste functie retourneert een andere functie die dus blijft refereren naar "v" zoals ie was toen is gedeclareerd werd. Die andere functie is dus de return waarde van de eerste functie en dat is wat er aan de onclick wordt gehangen

regel 14 behoeft uitbreiding :)

[ Voor 3% gewijzigd door Verwijderd op 29-11-2007 13:26 ]


  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 24-11 23:24
Juist. Dat werkt nu. Bookmarken dit topic :)

Alleen lijkt hij nu wel meteen de functie uit te voeren..... :?

JavaScript:
1
2
3
4
5
6
7
8
9
10
            tempVar = treeData[parentLevel+1][parentNode][u][0];
            tempLevel = parentLevel+1;
            if (treeData[parentLevel+2][tempVar] != undefined)
            {
                thistd.onclick = function(realVar, realLev)
                {
                    nextLevel(realVar, realLev);
                    showInfo(realVar);
                } (tempVar, tempLevel)
            }

iOS developer


Verwijderd

je leest nog steeds niet goed 8)
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
            tempVar = treeData[parentLevel+1][parentNode][u][0];
            tempLevel = parentLevel+1;
            if (treeData[parentLevel+2][tempVar] != undefined)
            {
                thistd.onclick = function(realVar, realLev)
                {
                    return function() {
                      nextLevel(realVar, realLev);
                      showInfo(realVar);
                    };
                } (tempVar, tempLevel);
            }

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 24-11 23:24
:X sorry

Maar het werkt perfect nu, nog wat kleine bugjes er uit werken en dynamische tree view in een tabel werkt :)

iOS developer

Pagina: 1