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

[JavaScript] navigatie en subnavigatie met actief item

Pagina: 1
Acties:

Verwijderd

Topicstarter
Dag jongens,

Ik ben al de hele avond bezig met een dynamisch navigatie menu en het gaat redelijk, maar ik kom er nu niet meer uit, wellicht dat jullie, met jullie totaal ruime expertise, mij verder kunnen helpen.

Heb nu een horizontaal menu, wat onder iedere kop weer een subnavigatie heeft. Wanneer ik met de muis over een kopje in het primary navigatie menu ga, komt het subnavigatietje tevoorschijn. Dat werkt allemaal goed.
Maar nu werk ik ook met actieve pagina's, zodat je in het menu eenvoudig kunt zien op welke pagina je nu zit. Dit werkt ook allemaal goed, maar wanneer je dan gaat kijken onder een ander kopje en je gaat vervolgens met de cursor weg, dan verdwijnt ook het actieve submenu en dat moet eigenlijk blijven staan.

Mijn vraag is dan ook:
Hoe kan ik, in JavaScript, zien, of de <li> van mijn primary navigatie <ul> de class "active" heeft. Om deze vervolgens bij een onmouseout van een andere <li> deze weer tevoorschijn te halen.

Hier volgt mijn code:

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
var navigationid=["navigation"]

function navigation()
{
    for (var i=0; i < navigationid.length; i++)
    {
        var ultags = document.getElementById(navigationid[i]).getElementsByTagName("ul")
        for (var t=0; t < ultags.length; t++)
        {
            ultags[t].parentNode.onmouseover=function()
            {
                this.getElementsByTagName("ul")[0].style.display="block"
            }
            ultags[t].parentNode.onmouseout=function()
            {
                this.getElementsByTagName("ul")[0].style.display="none"
            }
        }
    }
}

if (window.addEventListener)
    window.addEventListener("load", navigation, false)
else if (window.attachEvent)
    window.attachEvent("onload", navigation)


en dit is de
HTML:
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
  <ul id="navigation">
   <li class="active"><a href="#">Hier</a>
    <ul>
     <li><a href="#">Submenu 1</a></li>
     <li class="active"><a href="#">Is</a></li>
     <li><a href="#">Dit</a></li>
    </ul>
   </li>
   <li><a href="#">Komt</a>
    <ul>
     <li><a href="#">En</a></li>
     <li><a href="#">Dit</a></li>
     <li><a href="#">Is</a></li>
     <li><a href="#">submenu 2</a></li>
    </ul>
   </li>
   <li><a href="#">Natuurlijk</a>
    <ul>
     <li><a href="#">Dit</a></li>
     <li><a href="#">Vanzelfsprekend</a></li>
     <li><a href="#">Drie</a></li>
    </ul>
   </li>
   <li><a href="#">De</a>
    <ul>
     <li><a href="#">En</a></li>
     <li><a href="#">Ditte</a></li>
     <li><a href="#">Vier</a></li>
    </ul>
   </li>
   <li><a href="#">Navigatie</a>
    <ul>
     <li><a href="#">Maar</a></li>
     <li><a href="#">We</a></li>
     <li><a href="#">Hebben</a></li>
     <li><a href="#">Ook</a></li>
     <li><a href="#">Vijf</a></li>
    </ul>
   </li>
  </ul>


Ik heb al enkele dingen geprobeerd, maar ook getElementByClass wil niet werken.
Iemand enig idee?
Alvast bedankt!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Als ik zo naar je JS en HTML kijk denk ik maar 1 ding:

WAAROM :?

Met een paar goed geschreven regels CSS heb je geen enkel van die regels JS die jij geschreven hebt nodig :?

Verder, om wat inhoudelijk in te gaan op je JS probleem, je moet even kijken naar het 'scopen' van events in Javascript, danwel een frameworkje wat dit soort zooi voor je oplost op een x-browser manier.

Je gebruikt nu namelijk al 3 verschillende manieren om een event ergens aan te knopen, waarvan er waarschijnlijk al 2 niet werken :)

Stop uploading passwords to Github!


Verwijderd

SchizoDuckie schreef op zondag 03 augustus 2008 @ 00:30:
Als ik zo naar je JS en HTML kijk denk ik maar 1 ding:

WAAROM :?

Met een paar goed geschreven regels CSS heb je geen enkel van die regels JS die jij geschreven hebt nodig :?
Alleen CSS gebruiken voor menu's is ruk. CSS biedt geen ondersteuning voor enige intelligentie, timers, of wat dan ook.
Verder, om wat inhoudelijk in te gaan op je JS probleem, je moet even kijken naar het 'scopen' van events in Javascript, danwel een frameworkje wat dit soort zooi voor je oplost op een x-browser manier.

Je gebruikt nu namelijk al 3 verschillende manieren om een event ergens aan te knopen, waarvan er waarschijnlijk al 2 niet werken :)
Dat ben ik wel met je eens. Kijk bijvoorbeeld eens naar Prototype of MooTools.

  • Juup
  • Registratie: Februari 2000
  • Niet online
Verwijderd schreef op zondag 03 augustus 2008 @ 00:32:
Alleen CSS gebruiken voor menu's is ruk. CSS biedt geen ondersteuning voor enige intelligentie, timers, of wat dan ook.
SchizoDuckie zegt alleen dat de js die de TS gebruikt ook door CSS kan worden vervangen.
Voordeel: het rendert veel sneller dan javascript.
Nadeel: je moet trucken (bv. met <a/>'s) om het onder IE6 aan de praat te krijgen.

Een wappie is iemand die gevallen is voor de (jarenlange) Russische desinformatiecampagnes.
Wantrouwen en confirmation bias doen de rest.


  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Verwijderd schreef op zondag 03 augustus 2008 @ 00:32:
[...]

Alleen CSS gebruiken voor menu's is ruk. CSS biedt geen ondersteuning voor enige intelligentie, timers, of wat dan ook.
Klopt, maar ik vind het wel altijd een goede zaak om te zorgen dat dit soort dingen ook werken zonder Javascript, en dat kan best met een simpel regeltje css
Cascading Stylesheet:
1
#navigation:hover li.active UL { display:none; }


Dan kan eventuele usability trickery er best aan met wat regeltjes javascript :)
edit:
en voor IE 6 hovers is er clay's csshover.htc

[ Voor 6% gewijzigd door SchizoDuckie op 03-08-2008 01:56 ]

Stop uploading passwords to Github!


Verwijderd

SchizoDuckie schreef op zondag 03 augustus 2008 @ 01:51:

Klopt, maar ik vind het wel altijd een goede zaak om te zorgen dat dit soort dingen ook werken zonder Javascript, en dat kan best met een simpel regeltje css
Zonder Javascript werken zulke menu's voor geen meter. Je hoeft maar even een spastische beweging te maken, en er is alweer een menu afgesloten. Ik doe zulke dingen altijd met een korte timer of met een onmousedown/up, zodat je als je snel genoeg bent het menu nog open kunt houden. Zo werken menu's in bijvoorbeeld Windows ook. Niet alle mensen zijn even handig. Vanuit het oogpunt van accessibility hoor je ervoor te zorgen dat menu's een beetje vergevingsgezind zijn.

Tegenwoordig kan er al niemand meer Javascript. Als ze dan kutoplossingen gaan bedenken omdat Javascript "weleens uit zou kunnen staan" of "te moeilijk is", zie ik de toekomst somber in.

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Graceful degradation
Degradation of a system in such a manner that it continues to operate, but provides a reduced level of service rather than failing completely.
I rest my case wat dat betreft :) Overigens hoor je mij nergens dat het niet raadzaam is om er ook nog met js wat timers op te gooien, in tegendeel dat ben ik helemaal met je eens :) Mootools heeft een paar leuke events hiervoor, mouseenter en mouseleave (die net iets anders reageren dan mouseover en mouseout)

Het hele meukje staat hier beschreven
http://www.thetruetribe.c...eenter-and-mouseleave.php

[ Voor 38% gewijzigd door SchizoDuckie op 03-08-2008 02:39 ]

Stop uploading passwords to Github!


Verwijderd

Topicstarter
Uuhmm jongens,
Ik meen dat ik toch al redelijk goed op weg was met dit script. Ik zal voor de volledigheid ook maar even mijn CSS posten:

Cascading Stylesheet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ul#navigation { position: absolute; top: 0px; left: 0px; width: 942px; height: 24px; background-color: #c4ae89; border-top: 1px solid #fff; list-style: none; }
 ul#navigation li { height: 24px; border-right: 1px solid #fff; float: left; }
 ul#navigation li a { margin-top: -1px; padding: 0px 12px; font-size: 70%; letter-spacing: 1px; line-height: 24px; color: #fff; text-decoration: none; border-top: 1px solid #fff; display: block; }
 ul#navigation li a:hover { border-top: 1px solid #fff; background-color: #a99167; }

 ul#navigation li ul { position: absolute; top: 24px; left: 0px; width: 942px; height: 24px; display: none; z-index: 1; background-color: #cfbd9c; border-top: 1px solid #fff; list-style: none; }
 ul#navigation li ul li { float: left; }
 ul#navigation li ul li a { margin-top: 0px; border-top: 0px; }
 ul#navigation li ul li a:hover { border-top: 0px; }

 ul#navigation li.active a { margin-top: -1px; padding: 0px 12px; font-size: 70%; letter-spacing: 1px; line-height: 24px; color: #fff; text-decoration: none; border-top: 1px solid #840000; background-color: #840000; display: block; }
 ul#navigation li.active a:hover { border-top: 1px solid #840000; }
 ul#navigation li.active ul { display: block; }
 ul#navigation li.active ul li a { margin-top: 0px; border-top: 0px; background-color: #cfbd9c; }
 ul#navigation li.active ul li a:hover { border-top: 0px; background-color: #a99167; }
 ul#navigation li.active ul li.active a { margin-top: 0px; border-top: 0px; background-color: #a99167; }


Het enige dat ik wil weten is, hoe kan ik zien dat de <li> die ik heb ACTIVE is, zodat ik die bij mijn onmouseout, gewoon nog een display-block kan geven. Ik heb namelijk geen idee hoe ik dit hier nu moet doen.

Ik zoek geen oplossing in CSS, ik ken CSS als een tier en dat werkt nooit perfect, zoals hier boven ook al gezegd wordt. De beste manier is in dit geval Javascript. Tevens omdat ik het voor een systeem wil gebruiken voor een bedrijfje, en daar hebben ze allemaal Safari en JavaScript ondersteuning :-)

Wie kan me helpen met een methode om dus op de <ul> <li> (deze dus) de class uit te lezen.
Indien deze class dus active is, moet bij de onmouseout, van de <li>, de onderliggende <ul> dus de <ul> <li> <ul> gewoon de style display:block mee kan geven :) iedere keer :D.

Allemaal die ul, li, ul, li.. is het nog wel duidelijk?

Ow en wat betreft moo-tools enzo, geweldige dingen, maar dat heb ik juist niet nodig, ik wil gewoon een klein simpel javascript dat dit voor me zou kunnen doen.

edit:
overigens om de opmerking hierboven wat betreft usability te beargumenteren:
In de CSS die ik plaats zie je, dat er een bepaald secundair navigatie menu op display=block wordt gezet, dit is het submenu van de active primaire. Mocht JavaScript uit staan verliest dus heel de navigatie niet z'n functionaliteit. Overigens wil ik niet ingaan op dit soort dingen. Ik heb een duidelijke keuze vooraf gemaakt om dit met JS te doen, ik ken alle voor en nadelen van CSS en JS etc, maar ik kom gewoon even niet uit het GetElementByClass en de parentNode's. Dus ik wilde gewoon even een snelle blik op mijn JS door een hier zo vaak gevonden persoon met over het algemeen meer kennis van JS dan ik, om me even een heel stuk verder te helpen.
CSS kennis heb ik zeer voldoende, zoveel om te kunnen zeggen dat dit niet werkt met enkel CSS.

[ Voor 13% gewijzigd door Verwijderd op 03-08-2008 08:26 ]


  • SKiLLa
  • Registratie: Februari 2002
  • Niet online

SKiLLa

Byte or nibble a bit ?

Zoek je niet gewoon iets als: (myLi.parentNode.className == 'active' ) ?

'Political Correctness is fascism pretending to be good manners.' - George Carlin


Verwijderd

Topicstarter
SKiLLa schreef op zondag 03 augustus 2008 @ 08:42:
Zoek je niet gewoon iets als: (myLi.parentNode.className == 'active' ) ?
Ja zoiets, maar hoe kan ik dat dan direct inbouwen in het script wat ik nu heb dan?
Ik moet namelijk eerst kunnen zien welke <LI> de class active heeft en die moet ik dan bij iedere onmouseout, de <ul> die in de <li> die active is, op block kunnen zetten. En dat is wat ik niet voor elkaar krijg.

[ Voor 4% gewijzigd door Verwijderd op 03-08-2008 08:57 ]


Verwijderd

Dan zet je op regel 12 iets als
JavaScript:
1
2
3
if(this.parentNode.className != 'active'){
  this.getElementsByTagName("ul")[0].style.display="block";
}

Ik heb niet goed gekeken naar de precieze nesting van je ul's en li's, maar je snapt het idee.

Let wel, als je meerdere classes gaat gebruiken, dan moet je met indexOf kijken of die class erbij zit.

  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Verwijderd schreef op zaterdag 02 augustus 2008 @ 22:52:
Mijn vraag is dan ook:
Hoe kan ik, in JavaScript, zien, of de <li> van mijn primary navigatie <ul> de class "active" heeft. Om deze vervolgens bij een onmouseout van een andere <li> deze weer tevoorschijn te halen.
De class kun je opvragen met el.className. Het makkelijkst is om een variabele op het object te zetten die definieert of hij actief moet worden bij mouseout. Zoiets:

JavaScript:
1
2
3
4
5
6
7
            addEvent(ultags[t].parentNode,"mouseover",function() {
                this.oldClassName = this.className;
                this.className = "menuItemHover";
            });
            addEvent(ultags[t].parentNode,"mouseout",function() {
                this.className = this.oldClassName;
            });


Hierbij gebruik je een goede addEvent functie die cross-browser het this keyword correct laat werken.


Over de CSS/JS discussie die hier voor de 3014e keer wordt gevoerd:
1. JS beschikbaar? Gebruik JS voor menu
2. JS niet beschikbaar en IE>6 / fatsoenlijke browser? Gebruik CSS voor menu.
3. JS niet beschikbaar en IE<=6? Geef submenu van actief menu item weer met CSS.

Geen centje pijn, en iedereen krijg het optimale menu te zien. Ik snap niet waar verder nog discussie over mogelijk is.

TabCinema : NiftySplit


  • XWB
  • Registratie: Januari 2002
  • Niet online

XWB

Devver
Voor zulke menu's heb je altijd javascript nodig, al was het maar om het in IE6 werkend te krijgen. Of je wilt timers gebruiken. Ik doe het daarom altijd met javascipt, css enkel voor de opmaak. Daarnaast, javascript is erg leuk :)

Deze code komt van de vorige Tweakers.net layout, ik heb het alleen in een object gegoten, omdat objecten erg fijn werken.

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
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
function menu ( menuId )
{
    this.menu = document.getElementById ( menuId );
    this.timer = null;
    
    this.init();
}

Object.extend ( menu.prototype,
{
    init: function ()
    {
        if ( this.menu )
        {
            var liElements = this.menu.getElementsByTagName ( 'li' );
            var i = liElements.length;
            
            while ( i-- )
                liElements[i].onmouseover = this.showMenu.bind ( this, liElements[i] );
                
            this.menu.onmouseout = this.mouseOut.bind ( this );
            this.menu.onmouseover = this.mouseOver.bind ( this );
        }
    },
    mouseOver: function ()
    {
        if ( this.timer )
        {
            clearTimeout ( this.timer );
            this.timer = null;
        }       
    },
    mouseOut: function ()
    {
        this.timer = setTimeout ( this.hideMenus.bind ( this.hideMenus, this.menu, null ), 1000 );
    },  
    showMenu: function ( el )
    {
        var ul = el.parentNode;
        
        while ( ul )
        {
            if ( ul.tagName.toLowerCase() == 'ul' )
            {
                this.hideMenus ( ul, el );
                break;
            }
    
            ul = ul.parentNode;
        }
        
        var ul = el.firstChild;
        
        while (ul)
        {
            if (ul.nodeType == 1 && ul.tagName.toLowerCase() == 'ul')
            {
                ul.style.display = 'block';
                ul.style.visibility = '';
                break;
            }
            
            ul = ul.nextSibling;
        }   
    },
    hideMenus: function ( level, skipli )
    {
        var stack = [level];
        var i = 0;
        var li, j, el, tag;
        
        do
        {
            li = stack[i].childNodes;
            j = li.length;
            
            while (j--)
            {
                el = li[j];
                
                if (el.nodeType == 1 && el != skipli)
                {
                    tag = el.tagName.toLowerCase();
                    
                    if (tag == 'li')
                    {
                        stack[i++] = el;
                    }
                    else if (tag == 'ul' && el.style.display == 'block')
                    {
                        stack[i++] = el;
                        el.style.display = 'none';
                        el.style.visibility = 'hidden';
                    }
                }
            }
        }
        while (i--);
    }
});


JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Object.extend = function(dest, source, allowOverwrite)
{
    for (var prop in source)
    {
        if (source.hasOwnProperty(prop) && (allowOverwrite || !dest.hasOwnProperty(prop)))
            dest[prop] = source[prop];
    }
    
    return dest;
}

Object.extend(Function.prototype,
{
    bind: function()
    {
        var handler = this, args = [].slice.call(arguments, 0), object = args.shift();
        
        return function()
        {
            return handler.apply(object, args.concat([].slice.call(arguments, 0)));
        }
    }
});

March of the Eagles

Pagina: 1