[JS] troubles met objecten & recursieve functies

Pagina: 1
Acties:

  • Pelle
  • Registratie: Januari 2001
  • Laatst online: 14:18

Pelle

🚴‍♂️

Topicstarter
Goeiesavonds,

Voor de gein heb ik eens geprobeerd om wat zinnigs uit te halen met objecten in JS, en met recursieve functies. Ik had mezelf daar nog nooit echt in verdiept, en het leek me leuk om een soort van hierarchisch menu te maken, dat layers showt en hidet enzo.
Dit menu moet alle hoofdmenu-opties weergeven, en na het klikken op een menuitem moeten alle childs van de betreffende menuitem zichtbaar worden. Alle childs van andere menuopties moeten weer verdwijnen.

Enniewee, het is allemaal hier te zien: http://jj.upnet.nl/pelleDynMenu/

Ik ga de source niet hier posten, daar is het een veel te grote lap voor, maar ik heb in commentaar in ieder geval de (beoogde) werking neergezet, zodat jullie mijn onbegrijpelijke code wellicht nog een beetje kunnen snappen :)

Dit werkt perfect zoals ik zou willen. Geen probleem dus. Maar er treedt iets geks op wanneer je de dubbele slash voor menuItems["verhaaltje"].addChild("nee","http://www.nee.com"); weghaalt.

Om te kijken waar het probleem zat, heb ik her en der wat alert's geplaatst, en het blijkt dat de functie getSubs een onbekend object teruggeeft, en de functie hideLayer kan die dus niet hiden en dat genereert de foutmelding.
In regel 136 kan je ook de // (voor alert, in de functie hideSubItems) even weghalen om te zien welke zaken die functie retourneert.

Probeer dat maar eens zonder en met die child genaamd 'nee'. In het eerste geval gaat alles goed, in het tweede geval wordt er een undefined ge-alert.

* Pelle vind dit raar

Nog even wat puntjes:
* gebouwd op en getest in IE5.5
* alle code is gewoon te kopieren en in homesite of whatever te plakken om te kunnen testen, er wordt geen gebruik gemaakt van externe scripts of stylesheets.

Alle commentaar is natuurlijk welkom, ik kan me voorstellen dat mijn manier heel erg amateuristisch is, maar dat moeten jullie me maar vergeven.
Degene met de oplossing voor het probleem mag een biertje komen drinken hier :)

/edit
Klik maar eens even wat op about, en dan op fotos, en dan op contact ofzo, en weer terug om te kijken hoe ik vind dat het moet werken. Dit gaat dus fout wanneer die child van 'verhaaltje' (naam: 'nee') wordt toegevoegd.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

* drm heeft helaas niet al te veel tijd om er echt grondig naar te kijken

Maar ik zou zeggen:

Maak van het object menuItem een object wat de volgende properties en methods heeft:
code:
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
function menuItem ( name, link )
{
   /* Properties */
   this.link       = link == null ? "javascript:void(0);" : link;   // Link in the content frame
   this.name       = name;   // Name of the div-element
   this.children     = null;   // Array with child-objects
   this.nrOfChildren = 0;   // Number of children

   /* Method references */
   this.addChild = addChild;
   this.collapse = collapse;
   this.expand   = expand;
   this.openLink = openLink;
   this.show     = show;
   this.hide     = hide;

   /* Method definitions */

   // Adds a menu object to the menu item as a child
   function addChild ( menuItem )
   {
    this.children [ this.nrOfChildren ++ ] = menuItem;
   }

   // hides all children (collapses tree)
   function collapse ()
   {
    if ( this.children )
       for ( a in this.children )
        this.children [ a ].hide ();
   }

   // show all children (expands tree)
   function expand ()
   {
    if ( this.children )
       for ( a in this.children )
        this.children [ a ].show ();
   }

   // shows the current object by a "getElementById" reference
   function show ()
   {
    document.getElementById ( this.name ).style.display = "inline";
   }

   // hides the current object by a "getElementById" reference, and if children available, hide them too
   function hide ()
   {
    if ( this.children )
       this.collapse ();
    document.getElementById ( this.name ).style.display = "none";
   }

   function.openLink ()
   {
    top.frames [ 'contentFrame' ].location.href = this.link;
   }

   function writeOut ()
   {
    // deze mag je zelf doen :)
   }
}

Snappie het concept? Heb het niet getest, hoor, puur losse pols werk, maar volgens mij moet je meer in deze richting denken.

edit:
zag nog een foutje staan...

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

* drm kon het niet laten...

Ik heb het toch even uitgewerkt:
drm dynMenu

Ik bedacht me nog dat je voor het benaderen vanuit de html voor events e.d. wel een array nodig hebt om alle objecten in bij te houden.

Naja, see for yourself

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Pelle
  • Registratie: Januari 2001
  • Laatst online: 14:18

Pelle

🚴‍♂️

Topicstarter
Op woensdag 21 november 2001 13:09 schreef drm het volgende:
* drm kon het niet laten...

Ik heb het toch even uitgewerkt:
drm dynMenu

Ik bedacht me nog dat je voor het benaderen vanuit de html voor events e.d. wel een array nodig hebt om alle objecten in bij te houden.

Naja, see for yourself
* Pelle ziet dat drm er een stuk korter over deed dan Pelle

Hoewel, d'r zit natuurlijk wel een hoop gejat denkwerk in :)

Nu heb ik even geen tijd om het allemaal uitgebreid te gaan zitten bestuderen, maar op het eerste gezicht ziet het er goed uit. Iets wat ik wel wil (en waar ik ook in de eerste instantie aan dacht bij het toepassen van recursie (waarom? omdat ik daar volgende week een tentamen over heb, en JS oefent net wat lekkerder als Pascal :)), is als je (in jouw voorbeeld) dit hebt:
code:
1
2
3
4
main
  home
  contact
    melp

en je dan op home klikt, je dit krijgt:
code:
1
2
3
main
  home
  contact

Oftewel: alle childs van de items die dezelfde parent hebben als het item waar je op klikt, moeten ook gehide worden. (home heeft als parent 'main', dus voor alle items met parent 'main' moeten alle childs gehide worden, behalve voor het item zelf natuurlijk, want die moeten geshowed worden).

Iig, ziet er goed uit, als ik wat meer tijd heb dan duik ik even in de code. Kwas niet echt ingewijd in het OO-proggen, dus ik heb een hoop dingen te omslachtig aangepakt. Wel leuk om zo van je eigen fouten te leren overigens :)

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Op woensdag 21 november 2001 13:18 schreef Pelle het volgende:

[..]

* Pelle ziet dat drm er een stuk korter over deed dan Pelle

Hoewel, d'r zit natuurlijk wel een hoop gejat denkwerk in :)
Nahh het idee had ik al een keer eerder uitgewerkt, maar had het niet bij de hand ;)
* drm heeft ook al wel wat meer ervaring in OO

Ik had het toen alleen adhv van een UL/LI constructie gedaan. Het voordeel is dan, dat wanneer je het mainmenu sluit, en weer opent, de status van de children hetzelfde blijft.
Nu heb ik even geen tijd om het allemaal uitgebreid te gaan zitten bestuderen, maar op het eerste gezicht ziet het er goed uit. Iets wat ik wel wil (en waar ik ook in de eerste instantie aan dacht bij het toepassen van recursie (waarom? omdat ik daar volgende week een tentamen over heb, en JS oefent net wat lekkerder als Pascal :)), is als je (in jouw voorbeeld) dit hebt:
code:
1
2
3
4
main
  home
  contact
    melp

en je dan op home klikt, je dit krijgt:
code:
1
2
3
main
  home
  contact

Oftewel: alle childs van de items die dezelfde parent hebben als het item waar je op klikt, moeten ook gehide worden. (home heeft als parent 'main', dus voor alle items met parent 'main' moeten alle childs gehide worden, behalve voor het item zelf natuurlijk, want die moeten geshowed worden).
dat kun dus je ook oplossen door een ul te gebruiken ipv divs :)

Maar in principe is dat niet zo moeilijk te verwerken. Moet je alleen een soort van "restoreStatus"-property ofzo inbouwen voor de children van een object. En die dus aannemen zodra de parent zegt: "je mag je weer laten zien". ipv "je moet je weer laten zien".

* drm denkt dat Pelle daar best wel uitkomt
Iig, ziet er goed uit, als ik wat meer tijd heb dan duik ik even in de code. Kwas niet echt ingewijd in het OO-proggen, dus ik heb een hoop dingen te omslachtig aangepakt. Wel leuk om zo van je eigen fouten te leren overigens :)
jup. OO roelz :D

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz