Toon posts:

[js] onmouseout by DIV element

Pagina: 1
Acties:
  • 129 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Ik ben bezig met een simpel pop-up menu te maken mbv javascript. Ik doe dit redelijk op de standaard manier door een DIV met daarin een aantal links zichtbaar te maken zodra de mouse over het bovenliggende menu element komt (dit is een A element met een onmouseover attribuut).

Het probleem waar ik mee zit is dat het menu ook weer eens weg moet. Bij het verplaatsen van de muis naar een andere A gaat dit goed (ik zet de vorige DIV's visibility op 'hidden'), maar ik zit een beetje met de situatie waneeer een user zijn muis pointer buiten de pop-up (div) beweegt.

Logisch zou je zeggen dat je dit met "onmouseout" van het betreffende DIV element opvangt, maar ik merk dat die ook aangeroepen wordt als ik nog binnen het DIV element naar de verschillende hyperlinks die erin staan beweeg. Dat is natuurlijk niet de bedoeling.

Nu heb ik het op een omslachtige wijze weten te fixen door:

-de relatieve positie van het DIV element te vinden via een while loop en offsetParent/offsetTop/offfsetLeft
-de huidige grootte van het DIV element op te vragen (offsetHeight/Width)
-de huidige muis positie op te vragen met event.pageX/Y of event.clientX/Y
-checken of de coordinaten binnen de bounding box van het DIV element vallen.

Dit is een heel gedoe bij elkaar, en voor elke grootheid die ik opvraag heb ik weer 3 uitzonderingen zitten voor verschillende browsers. Het werkt wel, maar 'gedoe' werkt altijd incompatibiliteiten in de hand bij javascript.

Het liefst zou ik iets gebruiken zodat "onmouseout" alleen vuurt als ik de DIV container verlaat en NIET als ik naar 1 van de child elementen van deze container navigeer.

Weet iemand hoe ik dit zou kunnen doen?

Voor alle duidelijkheid, de browser waarmee ik test is firefox 1.04 onder Debian/Linux.

[ Voor 5% gewijzigd door Verwijderd op 08-08-2005 17:54 ]


  • Wacky
  • Registratie: Januari 2000
  • Laatst online: 28-04 21:25

Wacky

Dr. Lektroluv \o/

Kun je misschien wat code en/of een screenshot plaatsen?

Normaliter gebruik je een onmouseout met een div zo:
code:
1
<div onMouseOut="doedit();">

Dan zou de JS ook alleen uitgevoerd moeten worden als je de DIV verlaat

Nu ook met Flickr account


Verwijderd

Topicstarter
Het is eigenlijk redelijk recht toe recht aan:

HTML:
1
2
3
4
5
6
7
8
<DIV ID="testmenu" class="mymenu" STYLE="left: 0; background-color: #eeeeee; "
                        onmouseout="hideGivenMenu(event,'testmenu')"
                    >
    <a class="mylink" href="/test1"  style="width: 200;">&nbsp;test1</a><br>
    <a class="mylink" href="/test2"  style="width: 200;">&nbsp;test2</a><br>
    <a class="mylink" href="/test3"  style="width: 200;">&nbsp;test3</a><br>
    <a class="mylink" href="/test4"  style="width: 200;">&nbsp;test4</a><br>
</DIV>


Waarbij de huidige versie van de javascript functie is:

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
function hideGivenMenu(e, menuID) {    

    el = document.getElementById(menuID);
    var posx = findPosX(el);
    var posy = findPosY(el);    
    var width = getElementWidth(menuID);
    var height = getElementHeight(menuID);
    
    var mousex = 0;
    var mousey = 0;
    if (!e) {
        var e = window.event;
    }
    if (e.pageX || e.pageY) {
        mousex = e.pageX;
        mousey = e.pageY;
    }
    else if (e.clientX || e.clientY) {
        mousex = e.clientX + document.body.scrollLeft;
        mousey = e.clientY + document.body.scrollTop;
    }   
    
    if ( mousex >= posx+width || mousex <= posx || mousey >= posy+height || mousey <= posy ) {
        el.style.visibility = "hidden";
        el.style.top = -1000;
    }   
}


In de vorige versie had ik nog niet de bouding checks erin, en deze werd continue opgeroepen bij het navigeren (hoveren) naar de links. Enigste opmerking hierbij, dit gebeurde niet bij het hoveren boven de eerste link in het DIV element, maar wel bij een willekeurige andere (en natuurlijk als ik met de muis echt het DIV element verliet.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:52

crisp

Devver

Pixelated

Wat ik meestal doe is onmouseout een setTimeout starten, en die timeout bij een onmouseover weer cancellen. Door eventbubbling wordt de mouseover ook weer getriggerd direct nadat je over een child-element gaat waardoor de mouseout getriggerd werd.

Intentionally left blank


  • André
  • Registratie: Maart 2002
  • Laatst online: 13:59

André

Analytics dude

Vaak is een pause van 10ms al genoeg hiervoor, omdat de onmouseout en onouseover elkaar direct volgen.

Verwijderd

Topicstarter
André schreef op maandag 08 augustus 2005 @ 18:12:
Vaak is een pause van 10ms al genoeg hiervoor, omdat de onmouseout en onouseover elkaar direct volgen.
ok, dat betekent dus dat de post van Wacky ( "Dan zou de JS ook alleen uitgevoerd moeten worden als je de DIV verlaat" ) niet helemaal correct was en dat het gedrag wat ik bescheef dus volkomen normaal is?

Samengevat:

* Ik heb een A element die met onmouseover een DIV laat zien. De DIV bevat andere A's.
* Als ik over de child A's hover, wordt er een onmouseout voor de parent DIV gevuurt en meteen daarna een onmouseover voor die parent DIV.
* Omdat alleen het losse A element een onmouseover bevat die de DIV laat zien, verdwijnt de DIV.
* 1 oplossing is om de DIV naast een onmouseout, ook een onmouseover voor zichzelf te geven die de timeout cancelled die in de onmouseout was gezet.

Verwijderd

Topicstarter
Wat ik overigens wel merk dat de onmouseover op het DIV element die de clearTimeOut doet een zekere lag opleverd bij het hoveren over de linkjes in de DIV. Ik heb al geprobeerd met een aparte boolean bij te houden of de timeout active is (een enkele boolean test is wellicht goedkoper als een function call), maar dat hielp ook niet heel veel.

Bij een hover zet ik via CSS namelijk een andere achtergrond kleur. Zonder de onmouseover gaat het enorm soepel als ik met mijn muis over de links beweeg. Met de onmouseover reageert het net even trager. Het is mischien nauwelijks merkbaar als je het niet weet, maar toch.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:52

crisp

Devver

Pixelated

Verwijderd schreef op dinsdag 09 augustus 2005 @ 11:18:
[...]


ok, dat betekent dus dat de post van Wacky ( "Dan zou de JS ook alleen uitgevoerd moeten worden als je de DIV verlaat" ) niet helemaal correct was en dat het gedrag wat ik bescheef dus volkomen normaal is?
Dat gedrag is inderdaad normaal :)
Samengevat:

* Ik heb een A element die met onmouseover een DIV laat zien. De DIV bevat andere A's.
* Als ik over de child A's hover, wordt er een onmouseout voor de parent DIV gevuurt en meteen daarna een onmouseover voor die parent DIV.
Nee, de onmouseover wordt getriggered op je A, maar bubbled weer door naar je DIV :)
* Omdat alleen het losse A element een onmouseover bevat die de DIV laat zien, verdwijnt de DIV.
correct
* 1 oplossing is om de DIV naast een onmouseout, ook een onmouseover voor zichzelf te geven die de timeout cancelled die in de onmouseout was gezet.
ook correct :)

Intentionally left blank


  • frickY
  • Registratie: Juli 2001
  • Laatst online: 01-05 14:20
Nee, dit is geen normaal gedrag. Ook als je met je muis over de links beweegt bevind je je nog binnen de DIV. Maar nest om te beginnen die links eens netjes binnen een <p>-tag.

  • Arjan
  • Registratie: Juni 2001
  • Niet online

Arjan

copyright is wrong

frickY schreef op dinsdag 09 augustus 2005 @ 18:34:
Nee, dit is geen normaal gedrag. Ook als je met je muis over de links beweegt bevind je je nog binnen de DIV. Maar nest om te beginnen die links eens netjes binnen een <p>-tag.
Het mag dan geen normaal gedrag zijn, alle browser doen het op die methode.
De mooiste optie is laten checken of het item dat de mouse- over/out aanroept een child is van de div die je menu voorstelt :)

Wat ik zelf meestal doe omdat ik wat luier ben ;) is elk element binnen mijn menu dezelfde class geven. Voordat ik het menu laat verdwijnen check ik eerst even of ik wel daadwerkelijk naar een item ben gegaan dat geen onderdeel is van die class die alle items binnen mijn menu hadden :)

oprecht vertrouwen wordt nooit geschaad

Pagina: 1