Autor Zpráva
Suta
Profil
Přemýšlel jsem, jak vyřešit následující zadání (předesílám, že se jedná o webovou aplikaci závislou na javascriptu).

Mám položku, u níž chci při najetí myší zobrazit malý panel s možností tuto položku upravit, odstranit či přejmenovat. Přesněji řečeno, takovýchto položek může být ve stránce desítky až stovky:



1. První verzi jsem udělal tak, že každá položka již při vytvoření v sobě obsahuje onen panel s barevnými ikonami, pouze je skrytý pomocí display: none a css třída :hover onen panel zviditelní. Tuto verzi jsem zavrhl kvůli množství "nevyužitých" elementů spolu s přemýšlením nad verzí 2 (pokud by bylo ve stránce vloženo např. 100 položek, bylo by v případě tohoto prvního řešení vloženo dalších - byť skrytých - 400 elementů např. pro delete, update, info a open).

2. Tato přepracovaná verze vycházela z toho, že je vytvořen pouze jeden panel s ikonami a při zachycení události najetí na element je do něj vložen (při najetí na jiný prvek je opět vložen ten samý panel do nového prvku, čímž dojde automaticky k jeho odstranění z elementu předešlého). Jelikož toto řešení vyžaduje namísto událostí mouseover a mouseout využití mouseenter a mouseleave a tím pádem spoustu navázaných událostí, opět jsem se snažil jí vyhnout. Proto jsem přemýšlel dále.

3. Stačilo by, kdyby se v pravidelném intervalu (dejme tomu 800 milisekund) testovalo, zda-li je myš nad daným elementem. Pokud by pak myš setrvala nad danou položkou určitý čas (např. oněch 800 milisekund, byl by do položky vložen updatovací panel. Nepodařilo se mi však rozchodit otestování aktuálního targetu, na němž je myš v daný okamžik spuštění události setInterval (či setTimeout). Zdá se, že zde objekt event není dostupný?

Jediné, na co jsem zatím přišel je spojení události mousemove nad celou oblastí, při každém pohybu myši uložit aktuální target, a poté při spuštění časovače ověřit, zda-li je tento target onou položku a v případě že ano, vložit do něj můj malý updatovací panel.

Prosím o radu, co z toho je zcestné a co by mohlo být řešením. Díky všem.
Nox
Profil
1) Ale aspoň to bude statické, sice jich bude víc, ale nemusí se s tím manipulovat, navíc co je display:none se hádám ignoruje... ale ty další možnosti by mohly být lepší (v tvém případě je asi JS prostě předpoklad, jinak by tohle byla asi jediná volba)

2) "místo 2 událostí budou 2 a tím pádem spousta" => ??

3) Myslim že tahle možnost moc nativně není
Chamurappi
Profil
Reaguji na Sutu:
Chceš-li co nejvíc snížit počet elementů, stačí ti na všechna čtyři tlačítka jeden element.

Ad 2.) „vyžaduje namísto událostí mouseover a mouseout využití mouseenter a mouseleave“ — nevyžaduje a také nerozumím, o jakých navázaných událostech píšeš.
Možná, že by i bod 2 šel udělat přes :hover (tedy bez JavaScriptu), ale při prokliku bys pak musel docela obtížně zjišťovat, u které položky ten panýlek je :-)

Ad 3.) „Zdá se, že zde objekt event není dostupný?“ — není, časované události nemají žádné parametry (jediná výjimka je v Mozille — funkce dostává číslo, o kolik ms je volání zpožděné).
Suta
Profil
Chamurappi, Nox:
Ad 2.) ‚vyžaduje namísto událostí mouseover a mouseout využití mouseenter a mouseleave‘

Myslel jsem to tak, že mouseenter a mouseleave nejsou nativně dostupné ve všech prohlížečích. V případě použití událostí mouseover a mouseout pak dochází k jejich odpálení i v případě najetí na vnitřní elementy. Dříve jsem používal vlastní simulaci přesného chování mouseenter a mouseleave nejednoduchým scriptováním, nyní používám základní knihovnu jQuery, kde je robusnější řešení. Přesto se snažím použití této události minimalizovat, protože v případě, že není nativně podporována, jedná se o spoustu operací prováděných při pohybu nad vnitřními elementy.

Chceš-li co nejvíc snížit počet elementů, stačí ti na všechna čtyři tlačítka jeden element.
Můžeš to blíže rozvést?

Nox:
sice jich bude víc, ale nemusí se s tím manipulovat, navíc co je display:none se hádám ignoruje...
Věděl by někdo, jestli prvky s display:none skutečně nejsou ve všech prohlížečích brány v potaz např. při přesunu daného rodičovského elementu atd.?
_es
Profil
Suta:
V případě použití událostí mouseover a mouseout pak dochází k jejich odpálení i v případě najetí na vnitřní elementy.
No a to nejako výrazne vadí? Môžeš predsa zisťovať zdroj udalosti a podľa toho vetviť akciu, podobne ako napríklad tu. Alebo to zabezpečiť pomocou zastavenia prebublávania udalosti, možností je veľa.
Suta
Profil
_es:
Samozřejmě používám jak probublávání, tak delegování událostí na několik hlavních prvků (nepoužívám jednu jedinou na celý dokument). Tato cesta tedy možná je. Snažím se však hledat i jiné, šetrnější způsoby než spouštění spousty událostí a kontrolování targetu při najetí na každý prvek, jelikož můj projekt je poměrně rozsáhlý. Zatím nemám problém při použití žádného z výše uvedených způsobů, otázkou je, jak se prohlížeče s plně dynamickým webem vypořádají při naplnění obsahu. Proto moje obezřetnost a opatrnost, přestože někdy možná trochu přehnaná.

Jinak od probublávání pomalu upouštím zcela, jelikož jsem nasadil vlastní systém s unikátními názvy atributů u elementů, na nichž může být spuštěna nějaká událost. V jedné události nad celým dokumentem pak podle daného atributu spouštím odpovídající metodu s totožným názvem. Zatím se mi tento systém plně osvědčil z hlediska údržby a přehlednosti více, než kontrola jednotlivých targetů.
Chamurappi
Profil
Reaguji na Sutu:
<rýpnutí>
Myslel jsem to tak, že mouseenter a mouseleave nejsou nativně dostupné ve všech prohlížečích.
Nepodporující prohlížeče přeci můžeš poslat k čertu :-) … stejně za pár let budou tyto události nativně podporovat všichni. Firefox dokonce už od verze 10.
</rýpnutí>

pak dochází k jejich odpálení i v případě najetí na vnitřní elementy
Kolik jich uvnitř máš, že to vadí? Můžeš mít uvnitř každé položky jeden element překrývající celou plochu, který by sloužil jen k monitorování myši — tak to obvykle mívají mapové API.

vlastní simulaci přesného chování mouseenter a mouseleave nejednoduchým scriptováním
Ukážeš, prosím?

Můžeš to blíže rozvést?
Při kliknutí můžeš zjistit, na které místo v elementu se kliknulo, a mít všechny ty čudlíky jako (jedno) pozadí. Není to moc elegantní postup, ale je to méně elementů.

jestli prvky s display:none skutečně nejsou ve všech prohlížečích brány v potaz
Nedělal jsem si žádné výkonnostní testy, ale vím, že takto zneviditelněné elementy nemají v žádném prohlížeči změřitelné rozměry, takže předpokládám, že se s nimi nikdo nepáře. (Pokud neexistuje nějaká dynamická vazba, třeba display: inherit nebo hodnota s expression nebo behavior nebo -moz-binding…)
Suta
Profil
Chamurappi:
Rýpnutí beru jako částečně oprávněné. Přesto věř, že se snažím dělat vše proto, aby se mi spíše podařilo zoptimalizovat, než-li uživatele odhánět. S IE dosud nejsme kamarádi, nemám šanci zde vypsat vše, s čím i ve starších verzích prohlížečů nemám problém, jen při použití IE musím stále odstraňovat chyby. Možná je ale ta chyba i ve mně a nedostatečných znalostech pro aplikaci náročnějších požadavků.

Kód simulace mouseenter a mouseleave již nenajdu, používal jsem dříve. Jednalo se ale o funkci pro ošetření typické situace, kdy chceš spustit určitou akci při opuštění rodičovského elementu, a ona se ti spouští i na vnitřních prvcích. S postupným učením se javascriptu jsem tehdy vytvořil více verzí. Řešil jsem to počítáním targetů po vstupu do rodičovského elementu, později jsem měl problém s jeho hranou (hlavně tedy rámečkem border), kde se prohlížeče různily v tom, jak spouštěly událost a zda-li se tato událost schovávala pod mouseout či mouseover. Pro širší podporu jsem tehdy přidával i časování a kontrolu targetu, který následoval jako další target po najetí na hranu rodičovského elementu (targetu), abych určil, zda došlo k opuštění, či vstupu. Přesně si to již nepamatuji, jen že to bylo peklo. Dnes to beru jako školu, která mě posouvala dále.

Edit: Minulý týden jsem zde řešil kulaté rohy a css3. Výsledkem diskuze směrem ke mně je to, že jsem se rozhodl dělat je tak, aby byly kulaté i bez podpory css3 (či nebyly kulaté, ale byly). Když jsem však aplikoval "dobrou" radu a použil css :before a :after, byl to opět Internet Explorer 8, kdo jako jediný nepřekreslil stránku při odjetí z prvku, na něhož byla aplikována třída :hover a zároveň vnitřní prvek měl třídu :before (nebo naopak), takže ony kulaté rohy jaksi zůstávaly ve stránce. Jednalo se sice o složitou konstrukci ve stylu {#a .b:hover .c.d:before}, zajímavé na tom však bylo to, že žádný jiný prohlížeč v tom žádnou magii neviděl. Výsledkem pak bylo to, že jsem po odzkoušení všeho možného opět předělával celý stylopis bez použití :after a :before kvůli onomu jednomu. Víc na obhajobu mé nešťastné úvahy nemůžu říct.

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:

0