[JS/CSS] Javascript css menu hoverdelay

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • shappie
  • Registratie: December 2007
  • Niet online
Hallo,

ik ben al een tijdje bezig met websites maken en met alleen css en html lukt het al aardig. Net nadeel is dat ik nu tegen de tekortkomingen hiervan aanloop en er met javascript niet helemaal uitkom.

Ik heb een menu gemaakt wat opzich goed werkt alleen wil ik graag een delay op de hover. Als iemand nu even per ongeluk voorbij komt met zijn muis gaat meteen het menu naar een andere hover state. Ook wil ik graag dat als mensen met hun muis het menu verlaten het nog even zo blijft staan (weer een delay). Ik heb al heel wat af gegoogled en ben er zo achter gekomen dat dit niet meer met css alleen kan. Hiervoor is javascript nodig. Ik heb hierop ook gezocht en kwam op sites zoals deze:
http://www.dynamicdrive.com/dynamicindex1/chrome/index.htm

Dit is eigenlijk precies wat ik wil. Een wat kortere delay op de active state dus dat als je bijv naar je browser menu gaat je niet meteen een menu openklapt als je eroverheen komt. En dat als je per ongeluk even het menu verlaat met je muis het niet meteen weer inklapt.

Hier nog een goed voorbeeld: http://www.ledgernews.com/
Deze site heeft niet echt active hover maar omdat hij een vrij lange hover heeft als je het menu verlaat is het niet storend en ziet het er ook goed uit. Dit is dus ook een optie. (het beste zou natuurlijk zijn als je de delay van activate en deactive apart kan instellen)

Alleen hoe kan ik dit werkend krijgen met mijn code (zie code hieronder)?

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<div id="container">
    <div id="header_bg">
    <div id="header">
      <div id="menu_top">
        <ul>
          <li class="current"><a href="#">Menu 1</a>
            <ul>
              <li class="current"><a href="#">Submenu Item 1</a></li>
              <li><a href="#">Submenu Item 2</a></li>
              <li><a href="#">Submenu Item 3</a></li>
              <li><a href="#">Submenu Item 4</a></li>
              <li><a href="#">Submenu Item 5</a></li>
              <li><a href="#">Submenu Item 6</a></li>
              <li><a href="#">Submenu Item 7</a></li>
            </ul>
          </li>
          <li><a href="#">Menu 2</a>
            <ul>
              <li><a href="#">Submenu Item 1</a></li>
              <li><a href="#">Submenu Item 2</a></li>
            </ul>
          </li>
          <li><a href="#">Menu 3</a>
            <ul>
              <li><a href="#">Submenu Item 1</a></li>
              <li><a href="#">Submenu Item 2</a></li>
              <li><a href="#">Submenu Item 3</a></li>
              <li><a href="#">Submenu Item 4</a></li>
            </ul>
          </li>
        </ul>
        <div id="nav_bar"></div>
      </div>
    </div>
  </div>
  <div id="main">
    <div id="spacer_bg">
      <div id="spacer">
      </div>
    </div>
    <div id="mainbody_bg">
        <div id="mainbody">
        <div id="left">
        </div>
        <div id="content">
        </div>
      </div>
    </div>
  </div>
  <div id="footer_bg">
    <div id="footer">
    </div>
  </div>
</div>


Cascading Stylesheet:
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
    * {padding:0; margin:0;}
    body {font-family:Verdana, Arial, Helvetica, sans-serif; background:#4991f2;}
    div#container {}
    div#header_bg {background:#fff url(../images/test9/nav_bar.png) repeat-x bottom;}
    div#header {padding:50px 0 0 0; width:980px; margin:0 auto;}
    div#menu_top {background:#e5e5e5 url(../images/test9/menu_top.png);}
    div#nav_bar {position:relative; background:#ec763d url(../images/test9/nav_bar.png); width:100%; height:40px; margin:40px 0 0 0;}
    div#header ul {list-style:none; margin:0; padding:10px 0 0 10px; position:relative; z-index:1;}
    div#header ul:hover li.current a {background:#777 url(../images/test9/nav_deactive.png); width:140px;}
    div#header ul li {float:left; padding:0 10px 0 0;}
    div#header ul li:hover a,
    div#header ul li.current a,
    div#header ul:hover li.current:hover a {background:#ec763d url(../images/test9/nav_active.png); color:#fff;}
    div#header ul li a,
    div#header ul:hover li.current a {color:#ccc; display:block; text-align:center; text-transform:uppercase; text-decoration:none; font-size:16px; background:#777 url(../images/test9/nav_deactive.png); width:140px; padding:11px 10px;}
    div#header ul li ul,
    div#header ul:hover li.current ul {display:none;}
    div#header ul li:hover ul,
    div#header ul li.current ul,
    div#header ul:hover li.current:hover ul {display:block; position:absolute; left:0; top:50px; width:100%; margin:0; padding:2px 0 0 0;}
    div#header ul li:hover ul li,
    div#header ul li.current ul li {background:none; width:auto; position:relative;}
    div#header ul li.current ul li.current {background:none; width:auto; position:relative; z-index:1;}
    div#header ul li:hover ul li:hover,
    div#header ul li.current ul li:hover {background:none;}
    div#header ul li.current ul li.current:hover {background:none; width:auto; position:relative; z-index:1;}
    div#header ul li:hover ul li a,
    div#header ul li.current ul li a,
    div#header ul:hover li.current:hover ul li a {color:#ccc; font-size:12px; background:none; width:auto; padding:11px 10px;}
    div#header ul li.current ul li.current a,
    div#header ul:hover li.current ul li.current a {color:#fff; text-decoration:underline;}
    div#header ul:hover li:hover ul li a:hover,
    div#header ul:hover li.current ul li a:hover {color:#fff; text-decoration:underline;}
    div#header ul li.current ul li.current a:hover {color:#fff; text-decoration:underline;}
    div#main {}
    div#spacer_bg {border-top:10px solid #333; border-bottom:1px solid #fff; background:#555;}
    div#spacer {height:80px;}
    div#mainbody_bg {background:#ccc;}
    div#mainbody {height:400px;}
    div#left {}
    div#content {}
    div#footer_bg {background:url(../images/test9/footer_bg.png); border-top:10px solid #333;}
    div#footer {height:40px;}


Kan iemand mij helpen een zo'n simpel en kort mogelijke manier te vinden om dit menu (met puur li en ul elementen) via javascript een delay mee te geven.

PS. Ik wil dit later graag gaan gebruiken icm met een CMS systeem, dus ik kan niet teveel aan de code van het menu (HTML ul en li's) aanpassen, omdat als een CMS het menu beheert niet zomaar extra id's classes e.d. toegevoegd kunnen worden (dan moet alles hardcoded). Alles handmatig in de html code zetten is de laatste mogelijkheid.

Alvast bedankt, Shappie

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
shappie schreef op maandag 20 juli 2009 @ 22:33:
Kan iemand mij helpen een zo'n simpel en kort mogelijke manier te vinden om dit menu (met puur li en ul elementen) via javascript een delay mee te geven.
Kan iemand even...?
We zien hier graag wat je zelf al geprobeerd hebt, wat er niet werkt, waarom je denkt dat 't niet werkt etc. ;) We zitten hier niet om voor jou JS scriptjes in je HTML te bouwen ;)

En waarom kijk je bij die voorbeeldsites (of hell, scroll eens op deze pagina naar boven en zie dat wij hetzelfde idee gebruiken) niet eens in de broncode om daar van te leren hoe 't gedaan is/wordt?

[ Voor 15% gewijzigd door RobIII op 20-07-2009 22:47 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Da Weef
  • Registratie: Januari 2004
  • Laatst online: 15-09 09:16
Kan iemand mij helpen een zo'n simpel en kort mogelijke manier te vinden om dit menu (met puur li en ul elementen) via javascript een delay mee te geven.
Vinden is geen probleem:

-Google
-Tweede hit

:O

.


Acties:
  • 0 Henk 'm!

  • shappie
  • Registratie: December 2007
  • Niet online
Sorry dat het overkomt alsof ik er totaal geen moeite voor heb gedaan. Maar ik al heel wat af gegoogled.

@Da weef: tweede hit heb ik idd (al eerder) gevonden en geprobeerd. Dit had ik uiteindelijk goed werkend alleen heeft dit script de eigenschap nadat je de li weer verlaat dat hij de classes verwijderd van die li. Dit was voor mij niet echt een optie omdat hij dan de class current ook weghaalde... En ik zo dus geen current state meer kon aangeven. Voor de rest is dat script wel wat ik zoek.

@RobIII: Sorry dat het verkeerd overkwam ik heb al van alles geprobeerd was het alleen vergeten in de topic start te zetten (wat achteraf erg stom is omdat ik zelfs de FAQ nog had doorgelezen over ts maken). Hieronder een aantal opties die ik tot nu toe geprobeerd heb:

1. http://www.techno-soft.co...th-delay-using-javascript
Dit heeft zoals hierboven het gewenste effect van het delay maar heeft een lastige bijwerking dat het de class current weghaalt nadat je eenmaal de li hebt gehoverd. Als dit verholpen kan worden zou dit goed zijn. Ik kon in het javascript ook wel zien dat de classes van de li werden leeg gemaakt:
code:
1
2
3
4
  function deactivateMenu(ele) {
      var parent = ele;
      parent.className = "";
  }

Hier zou dus een optie moeten zijn die alleen de class "showMenu" verwijdert indien aanwezig...
Aangezien ik geen javascript programmeur ben kon ik dit niet zo snel vinden.

2. http://www.ledgernews.com/
Dit vond ik ook een mooie optie en hier heb ik dus ook de broncode van bekeken. Maar dit werkt heel anders. Het script heeft volgens mij per menu item een aparte optie dit is niet wat ik nodig heb omdat ik dan het javascript moet aanpassen als ik een link toevoeg (en uiteindelijk moeten ook leeks links kunnen toevoegen via een CMS systeem. Ik weet niet of het toch mogelijk is dit script zo aan te passen dat het werkt maar zo goed ben ik met javascript niet en ik heb het bekeken maar leek me niet mogelijk (voor mij).

3. http://www.tomanthony.co.uk/demo/delayed_CSS_menu/
Dit vond ik ook via google en heb ik ook naar gekeken. Deze persoon gebruikt alleen geen li en ul's voor zijn submenu. Ik heb de css zo aangepast dat het zou moeten werken maar toch lukte dit niet. Alleen de eerste link werkte met het JS en de 2de en 3de lieten helemaal geen submenu meer zien. Hierbij haakte ik dus ook af.

Er zijn nog wel een aantal sites die ik heb bekeken en waarvan ik de code heb gebruikt om te kijken of ik het werkend kreeg dit is ook allemaal niet gelukt helaas. Ik ben al een tijdje bezig met het proberen dus weet nit alles exact meer. De bovengenoemde 3 pogingen waren degene die het dichtste in de buurt kwamen.

Ik was nog niet op het idee gekomen om naar de tweakers.net bron te kijken maar dat zal ik nu eerst gaan doen.

Ik hoop dat het zo allemaal wat duidelijker is en jullie misschien wel kunnen helpen...

edit: Op tweakers is het menu ook gescheiden in 2 div's: "mainNav" "groupNav". Dit werkt dan heel anders dan dat er gewoon alleen ul's en li's zitten in dezelfde div. Ik kom er dan ook niet uit zo.

[ Voor 3% gewijzigd door shappie op 21-07-2009 18:10 ]


Acties:
  • 0 Henk 'm!

  • Duroth
  • Registratie: Juni 2007
  • Laatst online: 27-04-2016

Duroth

No rest for the tweaked

shappie schreef op dinsdag 21 juli 2009 @ 17:44:
@Da weef: tweede hit heb ik idd (al eerder) gevonden en geprobeerd. Dit had ik uiteindelijk goed werkend alleen heeft dit script de eigenschap nadat je de li weer verlaat dat hij de classes verwijderd van die li. Dit was voor mij niet echt een optie omdat hij dan de class current ook weghaalde... En ik zo dus geen current state meer kon aangeven. Voor de rest is dat script wel wat ik zoek.
Als dit je enige probleem is met het door Da Weef gegeven script, is een oplossing zo gevonden.
De meeste(?) JS frameworks hebben functies die je een specifieke class laten 'verwijderen' van een element. (linkje naar MooTools omdat ik dat redelijk vaak gebruik, er zijn natuurlijk tal van andere frameworks, zoals jQuery.) Sowieso bevatten beide frameworks prachtige oplossingen voor drop-down menu's, delays, in principe alles wat je zoekt. Misschien eens een wilelkeurig JS frameworkje pakken om daar wat mee te proberen? Scheelt je een hoop scripten, en het zal er uiteindelijk misschien nog beter uitzien ook.

Overigens, ook als een framework je te zwaar is, zal je waarschijnlijk toch vastzitten aan het dynamisch toevoegen / weghalen van classes. Dus het probleem met je 'current' class zal je, hoe dan ook, op moeten lossen.

Acties:
  • 0 Henk 'm!

  • shappie
  • Registratie: December 2007
  • Niet online
@Duroth
Een JS framework gebruiken is niet zo'n heel groot probleem. Ik kan de uiteindelijk sites toch vaak gewoon professioneel in een datacenter hosten (geen gratis/trage hosts ofzo) en volgens mij merk je dan niets/weinig van een js framework laden. Dus als het hiermee moet lukken zou dat ook perfect zijn.

Ik zal nog eens wat specifieker googlen nu ik weet dat het met jQuery of mootools moet lukken. Ik heb al wat linkjes gevonden die er veelbelovend uitzien dus dat ga ik zsm uitproberen.

Zou ik dit kunnen gebruiken? : http://javascript-array.c...ry_simple_drop_down_menu/

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Zou je het niet gewoon eens proberen? ;)
(Lees: why not? )

Then again vind ik voor een vertraging van 't sluiten van menuitems een complete jQuery/Mootools inzetten nogal overkill; en hey... de pagina waar je naar verwijst bevat ook nog eens een versie zonder complete libraries die nodig zijn: http://javascript-array.com/scripts/simple_drop_down_menu/. Joh! 8)

Nog beter/leuker is natuurlijk even zorgen dat je de paar regels JS die je nodig hebt hiervoor gewoon begrijpt en het zélf in je bestaande menu bouwt. Het is écht geen rocket science.

[ Voor 53% gewijzigd door RobIII op 21-07-2009 19:23 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • shappie
  • Registratie: December 2007
  • Niet online
@RobIII
Ik ben het ook al aan het proberen maar ik krijg het nog niet helemaal ok. De code opzich snap ik wel, spreekt nogal voor zich. Alleen als je nieuwe stukjes moet toevoegen of drastisch aanpassen gaat het soms fout. En die versie zonder library vereisen een aanpassing in de broncode wat niet de handig is als het via een CMS moet lopen. Maar de versie met jQuery werkt opzich goed. Alleen krijg ik een paar kleine dingen nog niet goed. Zo wil ik graag dat de menuItem (niet submenuItem) ook de hover state behouwt tijdens de delay. Dit krijg ik nog niet helemaal goed... Als ik er echt niet uitkom laat ik de code en preview hier nog wel zien.

En ik gebruik ook mijn eigen menu (met li's en ul's) dus ik implementeer het al in mijn eigen code. Tot zover alvast bedankt!

edit: Ik kom er niet uit hoe ik dat menu werkend krijg met mijn situatie en vooral de current state lukt me niet goed. Heeft iemand nog suggesties of voorbeelden (sites met een soortgelijk menu bijv.)?

[ Voor 11% gewijzigd door shappie op 22-07-2009 17:39 ]


Acties:
  • 0 Henk 'm!

  • shappie
  • Registratie: December 2007
  • Niet online
Heeft echt niemand een idee? Het meest ideaal zou zijn als er een optie is om een class toe te voegen en ook een specifieke class weer te verwijderen. Want nu krijg ik alleen maar 1 class toegevoegd en dan meteen alle classes verwijderd. Ook via google kom ik er niet uit helaas...

Acties:
  • 0 Henk 'm!

  • armageddon_2k1
  • Registratie: September 2001
  • Laatst online: 27-07 10:18
Probeer eens een Javascript library zoals mootools. Daar kan je gewoon element.addClass('test') doen en element.removeClass('test') doen. Scheelt een hoop gezeik.

Daarnaast kan je ook heel mooi groepen elementen selecteren. B.v. $('div#header li.class1 a') selecteert alle a-elementen onder de tag list (met classname class1) en die moet onder de div met id header zitten.

Het scheelt mij altijd een hoop gecode.

Engineering is like Tetris. Succes disappears and errors accumulate.


Acties:
  • 0 Henk 'm!

  • shappie
  • Registratie: December 2007
  • Niet online
armageddon_2k1 schreef op donderdag 23 juli 2009 @ 21:55:
Probeer eens een Javascript library zoals mootools. Daar kan je gewoon element.addClass('test') doen en element.removeClass('test') doen. Scheelt een hoop gezeik.

Daarnaast kan je ook heel mooi groepen elementen selecteren. B.v. $('div#header li.class1 a') selecteert alle a-elementen onder de tag list (met classname class1) en die moet onder de div met id header zitten.

Het scheelt mij altijd een hoop gecode.
Super bedankt! Ik gebruik dan jQuery (ik had al een script hiervan en heb dit dus aangepast, jQuery heeft ook de addClass en removeClass ingebouwd). Het enige wat ik nog niet helemaal goed krijg is om ook een mouseover delay in te bouwen. Dit moet niet zo lastig zijn maar ik krijg het niet goed erin. Dit is het menu wat ik gebruik:

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
var timeout    = 2500;
var closetimer = 0;
var parentlist = 0;
var menuitem = 0;

function nav_open()
{   nav_canceltimer();
    nav_close();
        parentlist = $('#nav').addClass("active")
        menuitem = $(this).addClass("hovered");}

function nav_close()
{       if(parentlist) parentlist.removeClass("active");
        if(menuitem) menuitem.removeClass("hovered");}

function nav_timer()
{   closetimer = window.setTimeout(nav_close, timeout);}

function nav_canceltimer()
{   if(closetimer)
    {  window.clearTimeout(closetimer);
        closetimer = null;}}

$(document).ready(function()
{   $('#nav > li').bind('mouseover', nav_open)
    $('#nav > li').bind('mouseout',  nav_timer)});

document.onclick = nav_close;


Ik heb al wat geprobeerd (nav_canceltimer bijv. ook bij nav_close zetten, maar dit werkt niet; wat ook wel weer logisch is). Dus heeft iemand een goede hint waar ik het moet zoeken om een (verschillend) delay te maken voor de mouseover (ik wil bijv. 100/200 ms op de mouseover op per ongeluk hover te voorkomen). Alvast super bedankt tot dusver!

Acties:
  • 0 Henk 'm!

  • Duroth
  • Registratie: Juni 2007
  • Laatst online: 27-04-2016

Duroth

No rest for the tweaked

De code staat al compleet in de snippet die je hebt geplakt ;) Zo moeilijk mag het echt niet zijn om zelf wat te verzinnen, dit gaat een beetje richting kant-en-klaar voorkouwen.

On-topic: Zoals je in je eigen snippet kan zien, roep je bij een onmouseout de nav_timer() functie aan. Deze zet een timer, en roept bij het aflopen van deze timer de nav_close() functie aan.

De nav_open() functie, daarentegen, roep je direct aan, zonder timer functie ertussen.

Afhankelijk van de behaviour waar je naartoe streeft, zou je b.v. met 2 timers kunnen werken. De eerste timer roept je nav_open() functie aan (en deze timer wordt uiteraard gereset op een onmouseout). De tweede werkt zoals je huidige timer, en roept nav_close() aan.
Een andere mogelijkheid is om nav_close() direct aan te roepen in je nav_open() functie, om ervoor te zorgen dat een reeds open menu direct gesloten wordt.

Kortom, ik zou even kijken wat je precies wilt, dit even stapsgewijs uitschrijven, en dan kijken wat de door jou geplakte code precies doet ;) Het lijkt nu alsof je maar wat in't wilde weg aan het proberen bent, en dat pakt lang niet altijd even goed uit.

Acties:
  • 0 Henk 'm!

  • shappie
  • Registratie: December 2007
  • Niet online
@Duroth
Erg stom van mij dat ik over het onderste stuk heen had gekeken daar werd inderdaad duidelijk de timer aangeroepen puur voor de nav_close function.

Ik heb het nu met 2 timers gemaakt alleen dit werkt niet (het idee van twee timers werkt wel), omdat bij de function nav_open het woord "this" wordt gebruikt werkt het niet meer. Omdat er nu een timer functie tussen zit, en dus niet meer direct wordt aangeroepen vanuit de mouseover functie lukt het niet (denk ik). En gewoon handmatig zoiets als: "#nav > li" invullen werkt niet omdat dan alle li's worden geactiveerd. Hoe kan ik toch de "this" laten werken (kan ik het element waar de mouseoser op slaat een naam geven (simpel gezegd) bijvoorbeeld)?


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
var timeout1    = 500;
var timeout2        = 1250;
var closetimer  = 0;
var parentlist  = 0;
var menuitem        = 0;

function nav_open()
{   parentlist = $('#nav').addClass("active");
        menuitem = $(this).addClass("hovered");}

function nav_close()
{       if(parentlist) parentlist.removeClass("active");
        if(menuitem) menuitem.removeClass("hovered");}

function nav_openDelay()
{       nav_canceltimer();
        closetimer = window.setTimeout(nav_open, timeout1);}

function nav_closeDelay()
{   nav_canceltimer();
        closetimer = window.setTimeout(nav_close, timeout2);}

function nav_canceltimer()
{   if(closetimer)
    {  window.clearTimeout(closetimer);
        closetimer = null;}}

$(document).ready(function()
{   $('#nav > li').bind('mouseover', nav_openDelay)
    $('#nav > li').bind('mouseout',  nav_closeDelay)});

document.onclick = nav_close;

Acties:
  • 0 Henk 'm!

  • Duroth
  • Registratie: Juni 2007
  • Laatst online: 27-04-2016

Duroth

No rest for the tweaked

Bijvoorbeeld door het element mee te geven in de aanroep naar nav_open(). Omdat binnen de functie openDelay 'this' wel naar je element refereert, zou je zoiets kunnen proberen: (met een commentje achter de aangepaste regels)

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
var timeout1    = 500;
var timeout2        = 1250;
var closetimer     = 0;
var parentlist     = 0;
var menuitem         = 0;

function nav_open(elem) // Aanpassing
{      parentlist = $('#nav').addClass("active");
         menuitem = $(elem).addClass("hovered");} // Aanpassing

function nav_close()
{        if(parentlist) parentlist.removeClass("active");
        if(menuitem) menuitem.removeClass("hovered");}

function nav_openDelay()
{        nav_canceltimer();
        closetimer = window.setTimeout(nav_open(this), timeout1);} // Aanpassing

function nav_closeDelay()
{      nav_canceltimer();
        closetimer = window.setTimeout(nav_close, timeout2);}

function nav_canceltimer()
{      if(closetimer)
       {  window.clearTimeout(closetimer);
          closetimer = null;}}

$(document).ready(function()
{      $('#nav > li').bind('mouseover', nav_openDelay)
       $('#nav > li').bind('mouseout',  nav_closeDelay)});

document.onclick = nav_close;


Let op, het is al laat, dus geen garanties ;-) Bovenstaand stukje code dient dan ook vooral om het principe te demonstreren. Maar zoals je ziet geef ik vanuit je openDelay het element ('this') mee aan de nav_open() functie.

Acties:
  • 0 Henk 'm!

  • shappie
  • Registratie: December 2007
  • Niet online
Ik heb de openDelay maar opgegeven want het heeft als nadeel dat als je dan meerdere item tegelijk kunt hoveren omdat de closeDelay groter is dan de openDelay. En ik ben eigenlijk ook wel tevreden met alleen een closeDelay.

Ik heb nu alleen een 3de lvl in het menu gemaakt dus zeg maar een dropdown van het submenu. Alleen dit krijg ik niet goed in orde. Zie hier preview: http://peterv.xs4all.nl/testing/menu/test6.php (hover "Submenu Item 2 +").

Het probleem is dat de li niet hoog genoeg is en dus als je onder de 1ste li item komt het menu weer inklapt. Ik heb al van alles geprobeerd in me css maar krijg het niet in orde. Hij staat op op overflow:auto; zodat je goed kunt zien tot welke hoogte hij het doet. Als ik hem op overflow:visible; zet zie je wel het hele menu uitgeklapt maar verdwijnt hij na de 1ste item. Hier de momentele JS code die ik gebruik om het 1ste level en 3de level een aparte timeout te geven:


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
var timeout     = 2500;
var timeout2        = 500;
var closetimer  = 0;
var parentlist  = 0;
var menuitem        = 0;
var submenuitem = 0;

function nav_open()
{   nav_canceltimer();
    nav_close();
    parentlist = $('#nav').addClass("active");
     menuitem = $(this).addClass("hovered");}

function nav_subopen()
{   nav_cancelsubtimer();
    nav_subclose();
     submenuitem = $(this).addClass("hovered2");}

function nav_close()
{   if(parentlist) parentlist.removeClass("active");
    if(menuitem) menuitem.removeClass("hovered");}

function nav_subclose()
{   if(submenuitem) submenuitem.removeClass("hovered2");}

function nav_timer()
{   closetimer = window.setTimeout(nav_close, timeout);}

function nav_subtimer()
{   closesubtimer = window.setTimeout(nav_subclose, timeout2);}

function nav_canceltimer()
{   if(closetimer)
    {  window.clearTimeout(closetimer);
        closetimer = null;}}

function nav_cancelsubtimer()
{   if(closesubtimer)
    {  window.clearTimeout(closesubtimer);
        closesubtimer = null;}}

$(document).ready(function()
{   $('#nav > li').bind('mouseover', nav_open)
    $('#nav > li').bind('mouseout',  nav_timer)
    $('#nav ul > li').bind('mouseover', nav_subopen)
    $('#nav ul > li').bind('mouseout', nav_subtimer)});

document.onclick = nav_close;


Om dit principe te laten werken moet de li.hovered2 natuurlijk wel het hele 3de lvl menu omvatten. Dit is nu niet het geval en ik krijg dit niet goed...

Weet iemand wat er fout zit (waarschijnlijk in de css aan te passen, maar ik vind de goede optie niet...)?

Acties:
  • 0 Henk 'm!

  • Da Weef
  • Registratie: Januari 2004
  • Laatst online: 15-09 09:16
De 3de level <ul> rekt de <li> niet uit en dat heeft waarschijnlijk te maken met positie eigenschappen. Dit is weer een gevolg van bepaalde inherits die in jouw css echt niet meer te volgen zijn.

Om maar een voorbeeld te noemen, met de declaratie waar je de overlow op auto zet voor het 3rd level, zet je ook css eigenschappen voor het 2nd level...

.


Acties:
  • 0 Henk 'm!

  • shappie
  • Registratie: December 2007
  • Niet online
@Da Weef
Dat was inderdaad ook wat ik als eerste dacht. Dat door de vele inherits er misschien iets verkeerd was ingesteld...

Ik heb nu dus al een paar uur aan het proberen geweest totdat ik op het idee kwam dat het javascript ook de opties gebruikt voor het 3de lvl menu. Daarom heb ik dus bijgevoegd in de code:
$('#nav ul ul > li').unbind();

Dit zorgde ervoor dat alles perfect werkte. Het was dus toch nog een javascript fout. Nu werkt alles zoals ik het wilde hebben, iedereen hier super bedankt voor de hulp!

Hier de code voor de geintresseerde:
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
        <ul id="nav">
          <li class="current"><a href="#">Menu 1</a>
            <ul>
              <li><a href="#">Submenu Item 1</a></li>
              <li class="current"><a href="#">Submenu Item 2 +</a>
                <ul>
                    <li><a href="#">Submenu Item 1</a></li>
                  <li class="current"><a href="#">Submenu Item 2</a></li>
                  <li><a href="#">Submenu Item 3</a></li>
                  <li><a href="#">Submenu Item 4</a></li>
                  <li><a href="#">Submenu Item 5</a></li>
                  <li><a href="#">Submenu Item 6</a></li>
                  <li><a href="#">Submenu Item 7</a></li>
                </ul>
              </li>
              <li><a href="#">Submenu Item 3 +</a>
                <ul>
                    <li><a href="#">Submenu Item 1</a></li>
                  <li><a href="#">Submenu Item 2</a></li>
                  <li><a href="#">Submenu Item 3</a></li>
                  <li><a href="#">Submenu Item 4</a></li>
                  <li><a href="#">Submenu Item 5</a></li>
                </ul>
              </li>
              <li><a href="#">Submenu Item 4</a></li>
              <li><a href="#">Submenu Item 5</a></li>
              <li><a href="#">Submenu Item 6</a></li>
            </ul>
          </li>
          <li><a href="#">Menu 2</a>
            <ul>
              <li><a href="#">Submenu Item 1 +</a>
                <ul>
                    <li><a href="#">Submenu Item 1</a></li>
                  <li><a href="#">Submenu Item 2</a></li>
                  <li><a href="#">Submenu Item 3</a></li>
                </ul>
              </li>
              <li><a href="#">Submenu Item 2</a></li>
            </ul>
          </li>
          <li><a href="#">Menu 3</a>
            <ul>
              <li><a href="#">Submenu Item 1</a></li>
              <li><a href="#">Submenu Item 2</a></li>
              <li><a href="#">Submenu Item 3 +</a>
                <ul>
                    <li><a href="#">Submenu Item 1</a></li>
                  <li><a href="#">Submenu Item 2</a></li>
                  <li><a href="#">Submenu Item 3</a></li>
                  <li><a href="#">Submenu Item 4</a></li>
                  <li><a href="#">Submenu Item 5</a></li>
                  <li><a href="#">Submenu Item 6</a></li>
                  <li><a href="#">Submenu Item 7</a></li>
                </ul>
              </li>
              <li><a href="#">Submenu Item 4</a></li>
            </ul>
          </li>
        </ul>

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
var timeout         = 2500;
var subTimeout      = 800;
var closeTimer      = 0;
var closeSubTimer   = 0;
var menuItem            = 0;
var subMenuItem     = 0;

$(document).ready(function(){
    $('#nav > li').hover(navOpen, navTimer);
    $('#nav ul > li').hover(subNavOpen, subNavTimer);
    $('#nav ul ul > li').unbind();});

function navOpen()
{   navCancelTimer();
    navClose();
        $('#nav').addClass("active");
        menuItem = $(this).addClass("hovered");}

function navClose()
{       $('#nav').removeClass("active");
        if(menuItem) menuItem.removeClass("hovered");}

function navTimer()
{   closeTimer = window.setTimeout(navClose, timeout);}

function navCancelTimer()
{   if(closeTimer)
    {  window.clearTimeout(closeTimer);
        closeTimer = null;}}
                
function subNavOpen()
{   subNavCancelTimer();
    subNavClose();
        subMenuItem = $(this).addClass("hovered2");}

function subNavClose()
{       if(subMenuItem) subMenuItem.removeClass("hovered2");}

function subNavTimer()
{   closeSubTimer = window.setTimeout(subNavClose, subTimeout);}

function subNavCancelTimer()
{   if(closeSubTimer)
    {  window.clearTimeout(closeSubTimer);
        closeSubTimer = null;}}

document.onclick = navClose;


Het mooie hieraan is dat het werkt zonder dat je in de html de code moet aanpassen (alleen de parent UL moet een id hebben), dit is ideaal voor CMS systemen zoals joomla waarbij je de (leek) gebruiker niet de html code handmatig kan laten aanpassen.

Bedankt voor alle hulp!

edit: Topic is opgelost. Ik kan zelf nergens vinden hoe dit te markeren dus ik vermeld het er maar even bij.
Pagina: 1