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

[JavaScript] Layer verbergen bij onmouseout

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben bezig met een pagina waar een submenu in een layer staat. Hiervan staat de visibility standaard op hidden. Bij het onmouseover event van een button wordt deze via een kleine JavaScript functie op visible gezet. Nu wil ik dat zodra de gebruiker met de muisaanwijzer uit het submenu gaat, dat de layer weer op hidden komt te staan. Daarom dacht ik hem weer te verbergen bij het onmousout event van de <div>. Het probleem is dat dit event veel te snel getriggered wordt. Al op het moment dat je naar een andere button gaat binnen het submenu gaat dit event af. Mijn vraag is of jullie een betere manier weten om dit te doen. Dus dat de layer pas verborgen wordt zodra je met de muispointer helemaal uit het submenu bent.

De relevante code is ongeveer als volgt:

Laten zien/verbergen van de layer.
code:
1
2
3
4
5
6
7
8
9
10
11
   function showLayer(layer_id) 
   {
     var obj = document.getElementById(layer_id);
     obj.style.visibility = "visible";
   }    
   
   function hideLayer(layer_id) 
   {
     var obj = document.getElementById(layer_id);
     obj.style.visibility = "hidden";
   }


De laag die het submenu bevat:
code:
1
2
3
4
5
<div style="position: absolute; background-color: white; z-index: 1; left: 27%; top: 40%; visibility: hidden; width=125; height=125" onmouseout="hideLayer('layer_subactivities')" id="layer_subactivities">
<table width=125 border=0 cellpadding=0 cellspacing=0>
<!-- Hier staan alle submenubuttons in -->
</table>
</div>


En deze laag wordt dus gedisplayed zodra de onmouseover van één van de buttons afgaat. Hopelijk hebben jullie een suggestie om me verder te helpen. Bedankt alvast in ieder geval.

  • Pkunk
  • Registratie: December 2003
  • Laatst online: 02-11 10:08
Ik zou het niet met javascript, maar met ccs doen. Hier staan een heleboel voorbeelden:
http://css.maxdesign.com.au/listamatic/

Hallo met Tim


  • Borizz
  • Registratie: Maart 2005
  • Laatst online: 24-09 20:59
@Timlog:
Ik ben het niet met je eens een menu verbergen / tonen heeft niets met opmaak (CSS) te maken maar met behaviour waar je dus JavaScript voor zou moeten gebruiken. Een mooi artikel hierover is On separating style and behaviour.

Maar dit lost het probleem van de TS nog niet op. Volgens mij hoort het onmouseout event pas op te treden wanneer je het element echt verlaat met de cursor en niet wanneer je over een childelement beweegt.
Er zit in ieder geval een fout in de style die je (inline) definieerd op je div, width=125 en height=125 kan natuurlijk nooit in css.. Gebruik je soms flash voor je buttons (of een andere plugin, java?).

If I can't fix it, it ain't broken.


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

Bozozo

Your ad here?

Je kunt width en height best in de CSS zetten hoor. Er moet eigenlijk nog wel 'px' achter de waarden staan.

Over je probleem: ik denk dat je de event listeners moet toekennen aan een wrapper div om het hele menu item (dus menu item en dropdown) heen.

Ik heb de indruk dat je gewoon een dropdown menuutje wilt maken; kijk idg even naar Suckerfish dropdowns.

TabCinema : NiftySplit


  • Borizz
  • Registratie: Maart 2005
  • Laatst online: 24-09 20:59
Bozozo schreef op zondag 06 april 2008 @ 19:52:
Je kunt width en height best in de CSS zetten hoor. Er moet eigenlijk nog wel 'px' achter de waarden staan.
Daar gaat het niet om het gaat om de syntax er staat width=125 terwijl het width: 125px zou moeten zijn. Afhankelijk van de mode waarin je pagina gerenderd wordt (standards compiance / quirks) is een unit (in dit geval px) verplicht.
Over je probleem: ik denk dat je de event listeners moet toekennen aan een wrapper div om het hele menu item (dus menu item en dropdown) heen.
Heb je zijn code wel bekeken? Het event wordt op de div gedefinieerd.
Ik heb de indruk dat je gewoon een dropdown menuutje wilt maken; kijk idg even naar Suckerfish dropdowns.
Zie ook mijn vorige reply over het scheiden van style en behaviour..

If I can't fix it, it ain't broken.


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

Bozozo

Your ad here?

Hmm, slecht gelezen.

Ik heb zelf ook een keer dit probleem gehad. Uiteindelijk heb ik gewoon alle subitems dezelfde event listeners gegeven als de main items. Als de muis een main item verlaat en tegelijkertijd een subitem binnengaat dan wordt het sumenu verborgen en weer getoond.

Deze oplossing resulteerde in een Suckerfish menu met toegevoegde JavaScript hipheid. Ik denk dat de source daarvan je een eind op weg zal helpen.

PS: het scheiden van stijl en behavior moet je niet te ver doorvoeren. Als CSS echt beter werkt dan JS (zoals het Suckerfish menu) dan moet je het m.i. gewoon gebruiken.

[ Voor 15% gewijzigd door Bozozo op 06-04-2008 22:41 ]

TabCinema : NiftySplit


  • Borizz
  • Registratie: Maart 2005
  • Laatst online: 24-09 20:59
Bozozo schreef op zondag 06 april 2008 @ 22:38:

PS: het scheiden van stijl en behavior moet je niet te ver doorvoeren. Als CSS echt beter werkt dan JS (zoals het Suckerfish menu) dan moet je het m.i. gewoon gebruiken.
Wie zegt dat css beter werkt voor menu's? Je kan prima vergelijkbare menu's met javascript maken.. Met javascript kan je het menu nog beter toegankelijk maken ook door bijvoorbeeld het menu item nog een aantal (mili)seconden te laten staan als je toevallig even net met je muis buiten het menu (item) komt. Bij een puur CSS menu zou dan heel je menu alweer verborgen / ingeklapt zijn.

Je kan CSS en javascript prima combineren om er iets moois van te maken, maar let dan wel op wat je in CSS doet en wat in JavaScript.

If I can't fix it, it ain't broken.


Verwijderd

Topicstarter
Er zit in ieder geval een fout in de style die je (inline) definieerd op je div, width=125 en height=125 kan natuurlijk nooit in css.. Gebruik je soms flash voor je buttons (of een andere plugin, java?).
Het toevoegen van 'px' heeft voor de rest geen invloed gehad op de werking van mijn pagina. Ik gebruik geen Flash, maar heb met ImageReady het menu gemaakt. De buttons zijn allemaal images en op de onmouseover wordt er een javascript functie aangeroepen die het image vervangt voor de rollover variant.

De functie om een image te veranderen.
code:
1
2
3
4
5
6
7
8
9
10
   function changeImages() 
   {
      if (document.images && (preloadFlag == true)) 
      {
        for (var i=0; i<changeImages.arguments.length; i+=2) 
        {
          document[changeImages.arguments[i]].src = changeImages.arguments[i+1];
        }
      }
   }


Dit event gaat dus af voor iedere button in het submenu.
Ik heb de indruk dat je gewoon een dropdown menuutje wilt maken; kijk idg even naar Suckerfish dropdowns.
Ja, dat is inderdaad de bedoeling. Ik zal me eens verdiepen in het Suckerfish voorbeeld.

Bedankt allemaal voor jullie reacties!

  • Pkunk
  • Registratie: December 2003
  • Laatst online: 02-11 10:08
Verwijderd schreef op zondag 06 april 2008 @ 23:16:
[...]
Het toevoegen van 'px' heeft voor de rest geen invloed gehad op de werking van mijn pagina. Ik gebruik geen Flash, maar heb met ImageReady het menu gemaakt. De buttons zijn allemaal images en op de onmouseover wordt er een javascript functie aangeroepen die het image vervangt voor de rollover variant.

Dit event gaat dus af voor iedere button in het submenu.
Misschien kan je hiervoor een background image gebruiken die bij hover veranderd naar wat je wil.
Ik weet niet voor wat voor website het precies is, maar als je het simpel wil houden zou ik toch even kijken naar die css menutjes. Scheelt weer wat regeltjes code :)
Ik ben het op zich wel eens dat css eigenlijk niet bedoeld is voor zoiets, maar als het slechts om een simpel uitklap menutje gaat maak je het jezelf mijns inziens onnodig 'lastig' door javascript te gebruiken.

Hallo met Tim


  • g4wx3
  • Registratie: April 2007
  • Laatst online: 12-10 08:33
Borizz schreef op zondag 06 april 2008 @ 19:35:
Ik ben het niet met je eens een menu verbergen / tonen heeft niets met opmaak (CSS) te maken maar met behaviour waar je dus JavaScript voor zou moeten gebruiken. Een mooi artikel hierover is On separating style and behaviour.
Ik ben het voledig met je eens. Ik gebruik ook niet graag CSS voor behaviors, behale voor a:hover. Visuele feedback is belangrijk.

Nadeel is dat als javascript uit staat de site niet bestuurbaar is. FOUT!
Dat is een vaak gehoord argument, maar een misvertand.

Ik schrijf altijd unobstructive javacript, wat er op neer komt dat javascript compleet gescheiden is van de site (geen inline mouseover). En dat de site volledig werkt zonder javascript eer ik javascript toevoeg.


Ik heb hier in de "kelder" nog een "probeersel" liggen, misschien dat ik je daarmee op weg help?
-- ik heb er even wat bij gehackt om een timeout te maken, maar de timeout krijg ik na 6 uur zoeken nog steeds niet meer aan de praat...

JS:
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
toggle_queu = new Array();

function build_menu()
    {
    parent_ul = document.getElementById('ul_menu');
    build_menu_expander( parent_ul );
    }
function build_menu_expander( parent_ul )
    {
    parents_li = parent_ul.getElementsByTagName('li') //Verzameling van ALLE MOGELIJKE ouders maken
    for( i=0 ; i<parents_li.length ; i++ ) // Een voor een alle ouders verwerken
        {
        child_ul = parents_li[i].getElementsByTagName('ul'); // Verzameling van alle kinderen van deze ouder maken
        if ( child_ul.length > 0 ) //Alleen verder gaan als ouder (minstens) 1 kind heeft
            {
            parents_li[i].getElementsByTagName('ul')[0].className = 'hide';
        //  Methode 1
        //  parents_li[i].onmouseover = function()
        //      {getParent(this,'li').getElementsByTagName('ul')[0].className = 'show';};
        //  parents_li[i].onmouseout = function()
        //      {getParent(this,'li').getElementsByTagName('ul')[0].className = 'hide';};
        //  Methode 2
            parents_li[i].onmouseover = new Function("toggle_queu.push(this);toggle_queu_manager(toggle_queu,'show');");
            parents_li[i].onmouseout = new Function("toggle_queu_manager(toggle_queu,'hide');");
        //  parents_li[i].onmouseout = new Function("toggle_queu_manager(this , 'hide');");
            }
        }
    return true;
    }
function getParent(element, parentTagName)
    {
    if ( ! element )
    return null;
    else if ( element.nodeType == 1 && element.tagName.toLowerCase() == parentTagName.toLowerCase() )
    return element;
    else
    return getParent(element.parentNode, parentTagName);
    }
    

function toggle_queu_manager(toggle_queu , status)
{
        if(status == 'show')
        {
        while ( toggle_queu.length > 1 )
        {
        toggle(toggle_queu[0], 'hide')
        toggle_queu.shift();
        }
        element = toggle_queu[toggle_queu.length-1]
        toggle(element, 'show')
        }
        else
        {
    //  toggle(toggle_queu[0], 'hide')
        setTimeout("alert('"+toggle_queu.length+"')",500)
        setTimeout("toggle_queu('"+toggle_queu[0]+","+ 'hide'+"')",500)
        }
}
function toggle(element, status)
    {
    parrent = getParent(element,'li')
    menu = parrent.getElementsByTagName('ul')[0];
    menu.className = status;
    }
    


HTML:
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
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="vertical_menu.css">
<!--<link rel="stylesheet" type="text/css" href="horizontal_menu.css">-->
<script type="text/javascript" src="menu_expander.js"></script>

<title>menu expander</title>
<style type="text/css">
<!--

body{ 
    margin:0; 
    padding: 0;
    position:relative;
    }
.content
    {
    width: 100%;
    position:relative;
    background: #ccf;
    }
.menuwrapper input
    {
    /*display: none;*/
    visibility: hidden;
    }
.menuwrapper, .menuwrapper label
    {
    background-color: #5cc;
    }
.menuwrapper li li
    {
    background-color: #ccc;
    }
.menuwrapper li ul label
    {
    background-color: #5fc;
    }

.menuwrapper ul ul label
    {
    height: 1.5em;
    }
/*
.menuwrapper li li  
    {
    padding: 0.5em 0;
    }
*/
/* - - - - - - - - - - - */
.hide
    {
    display: none; 
    }
.show   
    {
    display: block; 

    background-color: #500;
    }

/* - - - - - - - - - - - */
-->
</style>
<script type="text/javascript">
<!--
function init_js()
    {
    document.getElementById('bodywrapper').className = 'bodywrapper';
    document.getElementById('menuwrapper').className = 'menuwrapper';
    document.getElementById('ul_menu').className = 'ul_menu';
    document.getElementById('contentwrapper').className = 'contentwrapper';
    document.getElementById('content').className = 'content';
    build_menu()
    }
-->
</script>
</head>
<body onload="init_js()">
<div id="bodywrapper">

<div id="menuwrapper">
<ul id="ul_menu">
    <li>
        <label><input type="checkbox" name="info_a" >info_d</label>
        <ul>
            <li><label><input type="checkbox" name="info_d_1">info_d_1</label>
                <ul>
                    <li><label><input type="checkbox" name="info_d_1_1">info_d_1_1</label></li>
                    <li><label><input type="checkbox" name="info_d_1_2">info_d_1_2</label></li>
                    <li><label><input type="checkbox" name="info_d_1_3">info_d_1_3</label></li>
                </ul>
            </li>
            <li><label><input type="checkbox" name="info_d_2">info_d_2</label>
                <ul>
                    <li><label><input type="checkbox" name="info_d_2_1">info_d_2_1</label></li>
                    <li><label><input type="checkbox" name="info_d_2_2">info_d_2_2</label></li>
                    <li><label><input type="checkbox" name="info_d_2_3">info_d_2_3</label></li>
                </ul>
            </li>
            <li><label><input type="checkbox" name="info_d_3">info_d_3</label>
                <ul>
                    <li><label><input type="checkbox" name="info_d_3_1">info_d_3_1</label></li>
                    <li><label><input type="checkbox" name="info_d_3_2">info_d_3_2</label></li>
                    <li><label><input type="checkbox" name="info_d_3_3">info_d_3_3</label>
                        <ul>
                            <li><label><input type="checkbox" name="info_d_3_3a">info_d_3_3a</label></li>
                            <li><label><input type="checkbox" name="info_d_3_3b">info_d_3_3b</label></li>
                            <li><label><input type="checkbox" name="info_d_3_3c">info_d_3_3c</label></li>
                        </ul>
                    </li>
                </ul>
            </li>
        </ul>
    </li>

    <li>
        <label><input type="checkbox" name="info_a" >info_a</label>
        <ul>
            <li><label><input type="checkbox" name="info_a_1">info_a_1</label></li>
            <li><label><input type="checkbox" name="info_a_2">info_a_2</label></li>
            <li><label><input type="checkbox" name="info_a_3">info_a_3</label></li>
        </ul>
    </li>
    <li>
        <label><input type="checkbox" name="info_b" >info_b</label>
        <ul>
            <li><label><input type="checkbox" name="info_b_1">info_b_1</label></li>
            <li><label><input type="checkbox" name="info_b_2">info_b_2</label></li>
            <li><label><input type="checkbox" name="info_b_3">info_b_3</label></li>
        </ul>
    </li>
    <li>
        <label><input type="checkbox" name="info_a" >info_c</label>
        <ul>
            <li><label><input type="checkbox" name="info_c_1">info_c_1</label></li>
            <li><label><input type="checkbox" name="info_c_2">info_c_2</label></li>
            <li><label><input type="checkbox" name="info_c_3">info_c_3</label></li>
        </ul>
    </li>
    
</ul>
</div>

<div id="contentwrapper">
    <div id="content">
        qsdqs
            <p>
            piouhpoipiu piuyhy oiu t
            </p>
            <div id="log"></div>
        </div>
    </div>
</div>

</div>
</body>
</html>


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
.contentwrapper
    {
    margin-left:160px;
    z-index:0;
    position:relative;
    }
.menuwrapper
    {
    width: 160px;
    float: left;
    z-index: 99;
    position:relative;
    }
.menuwrapper ul 
    {
    position:relative;
    width:100%;
    margin: 0;
    padding: 0;
    }
.menuwrapper li 
    {
    list-style-type: none;
    position:relative;
    width: 100%;
    clear: both;
    }
.menuwrapper label  
    {
    display: block;
    width: 100%;
    float:left;
    }
.menuwrapper li ul
    {
    position: absolute;
    left: 100%;
    }

[ Voor 3% gewijzigd door g4wx3 op 07-04-2008 06:23 ]

http://www.softfocus.be/


Verwijderd

Topicstarter
@Timlog en g4wx3: thanx voor jullie suggesties. Ga het vanavond uitproberen, moet nu even Oracelen.

  • Pkunk
  • Registratie: December 2003
  • Laatst online: 02-11 10:08
Sjezis wat een lap code. Volgens mij kan dat korter (als je dan toch JS wil gebruiken):
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
<html>
<head>
<style>
.hasJS .menuitem-collapsed .submenu {display:none;}
.hasJS .menuitem-expanded .submenu {display:block;}
</style>
<script type="text/javascript">
window.document.documentElement.className='hasJS';
var menuitem;
var timer;
function collapse(el) { menuitem = el; timer = setTimeout('collapseItem()',200; }
function collapseItem() { menuitem.className='menuitem menuitem-collapsed'; }
</script>
</head>
    <body>
        
<ul class="mainmenu">
    <li class="menuitem menuitem-collapsed" onmouseover="this.className='menuitem-expanded'" onmouseout="collapse(this)">Item 1
        <ul class="submenu" onmouseover="clearTimeout(timer);">
            <li class="menuitem">SubItem 1</li>
            <li class="menuitem">SubItem 2</li>
            <li class="menuitem">SubItem 3</li>
        </ul>
    </li>
    
</ul>

    </body>
</html>

Of zie ik nu iets over het hoofd?

[ Voor 14% gewijzigd door Pkunk op 07-04-2008 12:04 ]

Hallo met Tim


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

Bozozo

Your ad here?

Borizz schreef op zondag 06 april 2008 @ 23:03:
[...]

Wie zegt dat css beter werkt voor menu's? Je kan prima vergelijkbare menu's met javascript maken.. Met javascript kan je het menu nog beter toegankelijk maken ook door bijvoorbeeld het menu item nog een aantal (mili)seconden te laten staan als je toevallig even net met je muis buiten het menu (item) komt. Bij een puur CSS menu zou dan heel je menu alweer verborgen / ingeklapt zijn.

Je kan CSS en javascript prima combineren om er iets moois van te maken, maar let dan wel op wat je in CSS doet en wat in JavaScript.
Dat bedoel ik. Voor dropdowns vind ik dit de juiste manier van werken:
  • Javascript aanwezig: maak het menu met javascript. Je kunt dan effecten als beweging en vertraging gebruiken
  • Geen javascript, moderne browser: maak het menu met CSS, dwz de Suckerfish methode.
  • Geen javascript, oude browser (IE6 en lager): klap het submenu van het actieve main menu item uit, bijvoorbeeld in de vorm van een extra horizontale menubalk.
Op deze manier kan de grootst mogelijke hoeveelheid mensen op een zo prettig mogelijke manier navigeren.

edit: Hier een demo van, naar mijn idee, goede downgrading (gedrag van dit menu in bepaalde situaties gefaked).

[ Voor 9% gewijzigd door Bozozo op 07-04-2008 14:30 ]

TabCinema : NiftySplit

Pagina: 1