Autor Zpráva
Suta
Profil
Trápím se s technikou vytváření vysouvacího menu za pomocí javascriptu (neřešme, prosím, dále, proč nepoužiji čisté css).

Mám-li následující kód (vytvořený pro názornost):

<style>
#mujDiv { float: left; width: 200px; height: 300px; border: 1px solid red; }
</style>

<script>
function spust() {
document.getElementById("mujDiv").onmouseout = function() {
alert("Prvek opuštěn.");
}
}
</script>

<div id="mujDiv" onclick="spust()">
Kliknutím uvnitř tohoto divu se nastaví funkce, která po následném opuštění prvku
vyvolá hlášku alert.
</div>


Po kliknutí uvnitř prvku se nastaví funkce na opuštění prvku, která vyvolá hlášku alert. Zde je vše v pořádku.

Přidám-li však dovnitř prvku další obsah mimo textu (např. odkaz a, položku seznamu li atd.), spustí se funkce nejen při opuštění hlavního prvku (tak jak bych potřeboval), ale i po najetí na odkaz (položku seznamu, ...).

Jak z toho ven? Zmíněný princim se snažím aplikovat na menu, kdy po najetí na na kořenovou položku menu se zobrazí vnořené podmenu pomocí display:block a znovu se skryje (display: none) po opuštění prvku. Dle uvedeného příkladu mi však ke skrývání dochází i při přejetí položky podmenu, která je v hlavním bloku vnořená...

Díky předem za pomoc.

Ukázku jsem vytvořil zde:

http://petrzavicak.cz/editor/test.php
_es
Profil
Suta
Nerieši to ten problém, no tú funkciu môžeš spraviť takto:
<script>
function spust(x){
  x.onmouseout = function(){alert("Prvek opuštěn.");};
}
</script>

<div id=div_1 onclick="spust(this)">
Kliknutím uvnitř tohoto divu se nastaví funkce, která po následném opuštění prvku
vyvolá hlášku alert.
</div>
<div id=div_2 onclick="spust(this)">
Kliknutím uvnitř tohoto divu se nastaví funkce, která po následném opuštění prvku
vyvolá hlášku alert.
</div>
Možno by sa to dalo nejako vyriešiť skombinovaním s onmoseover.
Suta
Profil
_es
Pochopitelně třeba i takto, script jsem psal pro ukázku jednoduše. Nicměně problém

Přidám-li však dovnitř prvku další obsah mimo textu (např. odkaz a, položku seznamu li atd.), spustí se funkce nejen při opuštění hlavního prvku (tak jak bych potřeboval), ale i po najetí na odkaz (položku seznamu, ...).

to neřeší.

Věděl-li by někdo řešení, budu vděčný, nemůžu na to přijít.
_es
Profil
Pomocou onmouseout aj onmoseover by sa to teoreticky mohlo dať, keďže pri tom neželanom spustení funkcie nastanú ihneď za sebou obe udalosti a pri tom želanom len onmouseout. No možno ti niekto iný poradí niečo jednoduchšie a lepšie.
fajzen
Profil
po najetí na na kořenovou položku menu se zobrazí vnořené podmenu pomocí display:block a znovu se skryje (display: none) po opuštění prvku

síce to nie je univerzálne riešenie, ale tvoj problém s vysúvacím menu by to vyriešiť mohlo: predpokladám, že máš nejaké funkcie ukaz() a skry()... potom jednoducho zadáš funkciu ukaz() pri onmouseover a funkciu skry() pri onmouseout aj každému prvku podmenu...
pri opustení koreňovej položky alebo položky podmenu sa síce js pokúsi menu skryť, ale hneď sa aktivuje funkcia ukaz() ktorú vyvolá položka podmenu, na ktorú prejdeš, takže sa z pohľadu užívateľa nič nestane...
_es
Profil
fajzen, Suta
Neviem, či myslel fajzen to isté, no ak sa požije dvojica udalostí onmouseout a onmoseover na skrytie a zobrazenie niečoho iného podľa toho problematického DIVu, tak sa tie dve udalosti navzájom vyrušia pri vnútornom obsahu toho DIVu.
Teda po onmouseout nastane ihneď onmoseover.
Suta
Profil
Rozumím tomu, co máte na mysli a díky za radu, zkusím se s tím později potrápit, i když mi to přijde takové kostrbaté řešení.

Stále nevím, z jakého důvodu se přeruší funkce reagující na opuštění prvku s daným id v situaci, kdy je uvnitř daného prvku vnořený další prvek (odkaz, seznam...). Vypadá to na křížení DOMu, ale proč a dá-li se to ošetřit jinak než vámi předkládaným způsobem nevím.

Princip s onmouseout jsem chtěl využít na tomto menu, se kterým si právě hraji (ala windows). Zatím to mám na onclick. Takto je to samozřejmě i ve windows, programech, prohlížečích... Nicméně rád bych submenu skryl už po opuštění prvku...

Ukázka zde: http://petrzavicak.cz/editor
_es
Profil
Suta
i když mi to přijde takové kostrbaté řešení.

Je to predsa veľmi jednoduché:
onmouseout: skry submenu
onmouseover: zobraz podmenu
A funguje to aj na DIVy s tými vnorenými prvkami, no submenu sa teoreticky na nejakú milisekundu skryje a hneď sa zase zobrazí.
Prakticky sa skôr neskryje vôbec a tie vnorené prvky nebudú mať ten neželaný efekt.
Tie dve udalosti sú obe toho problematického DIVu.
Suta
Profil
Tak ještě jedna chuťovka. Nechci zakládat nové téma, jedná se o podobný problém jako výše.

Mám-li v seznamu vnořený další seznam s následujícím kódem:

<script>
function spust() {
alert("Funkce spuštěna.");
}
</script>

<ul>
  <li onclick="spust(this)"><a href="#">Spustit funkci</a>
    <ul><li onclick="spust(this)"><a href="#">Spustit funkci</a></li>
    </ul>
  </li>
</ul>


Pak při kliknutí na položku prvního seznamu se funkce spustí správně jednou, ale při kliknutí na vnořenou položku li se funkce spustí dvakrát (logicky...).

Já bych však potřeboval, aby se funkce spustila pouze jednou při kliknutí na konkrétní položku... (Dovedete si představit kolikrát by se provedlo volání funkce při dalších vnořených seznamech?)

Jde toho nějak docílit?
zvěřiňák
Profil *
Je zajímavé, že to spuštění funkce jednou i u vnořených položek li funguje, když onclick dám jenom u první položky li.
<script>
function spust() {
alert("Funkce spuštěna.");
}
</script>

<ul>
  <li onclick="spust()"><a href="#">Spustit funkci</a>
    <ul><li><a href="#">Spustit funkci</a>
        <ul><li><a href="#">Spustit funkci</a></li>
    </ul>
    </li>
    </ul>
  </li>
</ul>
Chamurappi
Profil
Reaguji na Sutu:
Stále nevím, z jakého důvodu se přeruší funkce reagující na opuštění prvku s daným id v situaci, kdy je uvnitř daného prvku vnořený další prvek
Protože při přejetí na potomka opouštíš území rodičovského elementu. V podstatě kurzor nemůže být na území dvou elementů naráz.

Vypadá to na křížení DOMu
Žádné křížení v tom není, jen to má trochu zvrácenou logiku.

Kluci z Microsoftu na tvůj problém vymysleli docela čisté řešení v podobě nových událostí onmouseenter a onmouseleave — ty dělají přesně to, co potřebuješ a neprobublávají ke svým rodičům. Tvůrci ostatních prohlížečů žádosti o jejich implementaci odmítli, protože mají strach, že by bůh zabil koťátko. Když si necháš vyhledat „onmoouseenter Mozilla“, najdeš nějaká řešení, ale nejsou moc hezká.

při kliknutí na vnořenou položku li se funkce spustí dvakrát (logicky...).
Je třeba zastavit bublání.
function spust(li, event)
{
  // …
  event.cancelBubble = true;
  if(event.stopPropagation) event.stopPropagation();
}
<li onclick="spust(this, event)"> …
zgr
Profil *
fajzen
díky díky díky, fachá to skvěle.
a navíc je to jednodušší než pomocí relatedTarget na www.quirksmode.org/js/events_mouse.html

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: