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

[js] onmouseover binnen nested li-ul vuurt te vaak

Pagina: 1
Acties:

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
Ik heb het volgende probleem:
Ik heb een menu waarvan sommige items een submenu hebben. Dit submenu toon ik dmv een onmouseover op de li waaronder die valt en dat ging goed, totdat ik een bepaald effect wilde inbouwen. Toen bleek dat dat effect bij elke beweging van m'n muis opnieuw optrad.

Ik heb de volgende testcase:

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
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
 <title>Untitled Document</title>
 <style type="text/css">
#menu {
    list-style: none;
    }
#menu LI.mainItem {
    width: 100px;
    border: 1px solid black;
    float: left;
    padding: 2px 5px;
    }
#menu LI.mainItem UL {
    background-color: #EEE;
    }
#debug {
    width: 500px;
    height: 300px;
    overflow: auto;
    border: 1px solid green;
    }
 </style>
 <script type="text/javascript">
 function initEffects()
 {
    var lis = document.getElementById('menu').getElementsByTagName('LI');
    for (var l=0; l<lis.length; l++)
    {
        if (lis[l].className.match(/mainItem/))
        {
            lis[l].onmouseover = function () {
                debug('over: '+this.id);
            }
            lis[l].onmouseout = function () {
                debug('out: '+this.id);
            }
        }
    }
 }
 function debug(str)
 {
    document.getElementById('debug').innerHTML += str+'<br>\n';
 }
 </script>
</head>

<body onload="initEffects();">

<ul id="menu">
 <li class="mainItem" id="1-1">
    Item
    <ul>
     <li id="2-1">SubItem1</li>
     <li id="2-2">SubItem1</li>
     <li id="2-3">SubItem1</li>
     <li id="2-4">SubItem1</li>
    </ul>
 </li>
 <li class="mainItem" id="1-2">nog een item</li>
</ul>


<div id="debug"></div>
</body>
</html>


Dit test-geval logt in het debug-divje van welke li de onmouseover gevuurd wordt. De output zal er zo uitzien, ook als je over de subitems van 1-1 heen gaat:

code:
1
2
3
4
5
6
7
8
9
10
11
over: 1-1
out: 1-1
over: 1-1
out: 1-1
over: 1-1
out: 1-1
over: 1-1
out: 1-1
over: 1-1
out: 1-1
over: 1-1


Dus, ter verduidelijking:
Als je met je muis op LI met id=1-1 gaat staan, dan vuurt de onmouseover van die LI. Beweeg je je muis horizontaal, dan gebeurt er niets. Beweeg je je muis nu naar beneden, dan zal de onmouseover van LI 1-1 nogmaals vuren op het moment dat je op een sub-li komt. Beweeg je 'm verder naar beneden: again. Dus bij iedere overgang van een LI (ook de 2-1, 2-2, etc.) vuurt de onmouseover van 1-1

Ik snap ten eerste dit gedrag niet, want ik zou maar 1x vuren verwachten. Toch gaat het structureel in iedere browser (IE, FF, Opera) fout.
Heeft iemand een verklaring voor dit verschijnsel? Kon met google alleen het probleem vinden, maar geen oplossing of verklaring.

btw: Normaal merk je hier niets van omdat na de onmouseout gelijk de onmouseover weer vuurt, tenzij je - zoals in mijn geval - een effectje met een delay aan het inbouwen bent.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:18

crisp

Devver

Pixelated

Dat heet event-bubbling en is inderdaad gedefinieerd gedrag. De oplossing is of te werken met timers die je weer cancelled als na een mouseout weer een mouseover wordt afgevuurd, of door te kijken welk element het event triggerde en op basis daarvan wel of geen actie te ondernemen.

IE heeft hiervoor de mouseenter/leave events, maar andere browsers hebben dit (nog) niet geimplementeerd (is in een custom eventhandler overigens wel te immiteren, dat doen wij bijvoorbeeld op de frontpage).

Intentionally left blank


  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
crisp schreef op vrijdag 19 september 2008 @ 16:27:
Dat heet event-bubbling en is inderdaad gedefinieerd gedrag.
ahhhhh....tja, daar zeg je wat :-)
De oplossing is of te werken met timers die je weer cancelled als na een mouseout weer een mouseover wordt afgevuurd, of door te kijken welk element het event triggerde en op basis daarvan wel of geen actie te ondernemen.
Ik zou het liefst voor optie twee gaan, maar hoe achterhaal ik dat dan? Want als ik m'n muis over LI 2-1 of 2-2 beweeg dan logt ie in m'n debug-div dat het LI 1-1 is geweest.

  • Cartman!
  • Registratie: April 2000
  • Niet online
Beetje offtopic maar niet geheel onbelangrijk: je id's zijn niet in orde...zie de parser. Zulk soort zaken kunnen de boel soms behoorlijk laten buggen (en terecht imo)

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
Cartman! schreef op vrijdag 19 september 2008 @ 18:51:
Beetje offtopic maar niet geheel onbelangrijk: je id's zijn niet in orde...zie de parser. Zulk soort zaken kunnen de boel soms behoorlijk laten buggen (en terecht imo)
Was alleen ter illustratie ;)
Ik geef op de echte pagina gelukkig betere namen aan m'n ids dan 1-1, enzo :)