ugrás a tartalomhoz

diszkrét javascript esemény forrása

teamtom · 2007. Már. 10. (Szo), 15.59
Tisztelt JS guruk,

a diszkrét javascript és az eseménykezelés mélységeinek tanulmányozására létrehozott fájlom furcsán működik.
Az a tény, hogy következetesen ugyanazt csinálja IE6-ban és FF1.5 alatt is, azt sugallja, hogy én értek valamit félre. Tehát:

Egy paragrafusban van egy <em> elem, az onclick esemény (szinezd pirosra!) a paragrafusra van regisztrálva
Ha a P-re kattintok, beszinezi a P-t. Ha az EM-re kattintok, csak az EM lesz színes, holott én azt várnám, hogy az esemény felfelé "buborékol" egészen a P-ig és ott "is" végrehajtódik

valóban ez a helyes viselkedés? többféle szakirodalomból dolgozva próbálkoztam átírni, javítani a szkriptet, de mindig így működött
mit értelmezek félre?

a tesztoldal itt van

az első "lorem ipsum"-ban a második mondat az EM elem

mi hát az igazság?

Köszönöm: teamtom
 
1

bocsánat...

teamtom · 2007. Már. 10. (Szo), 16.03
a post témája, címe csonka maradt...
tudom javítani valahol?
ha nem, kérem a moderátort, hogy javítsa/egészítse ki "a diszkrét javascript + eseménykezelés furcsasága"-ra

köszönöm, és elnézést!
2

target

vbence · 2007. Már. 10. (Szo), 16.23
Van egy ilyened:
var evt = e || window.event;
var s = evt.target || evt.srcElement;
Ez (mint az ábra mutatja) az eseményt kibáltó objektumot adja vissza, nem pedig azt, ahol a kód végrehajtódik. Hiába buborékol felfele, a kattintás akkor is az EM elemen volt. Most lusta vagyok átnézni a referenciát, de van valami currentTarget, ennek nézz utána. Persze máshogy lesz IE-ben és nem-IE-ben.
3

currentTarget

teamtom · 2007. Már. 10. (Szo), 16.45
a W3C verziójában létezik a currentTarget property, de az IE-ben nincs hasonló

a currentTarget ez esetben valóban a P-re mutat, FireBuggal ellenőriztem

azt hittem, hogy a "bubble up" valami automatizmust jelent
nyilván nem gondoltam végig

a problémám az, hogy most általában foglalkoztat a kérdés, a válaszod viszont azt sugallja, hogy nincs általánosan szép, kerek megoldás, csak egyedi esetek vannak, amit feladatspecifikusan kell lekezelni
4

csak van...

vbence · 2007. Már. 10. (Szo), 18.25
Biztosan van az IE-ben is hasonló objektum. Nyomtasd ki az event objektumot, és nézd végig.. itt egy okosság:
http://vbence.web.elte.hu/dom_objektum_info.html

A mostani változatod is lekezeli az IE és nem-IE különbséget (target vs. srcElement), csak ezeket a neveket kell módosítani, és van egy ugyanennyire "univerzális" megoldásod, ami azt csinálja, mint szeretnél.
5

IE vs. currentTarget

teamtom · 2007. Már. 10. (Szo), 19.27
Peter Paul Koch írja az oldal alja felé currentTarget alcím alatt:

"To solve this problem W3C has added the currentTarget property. It contains a reference to the HTML element the event is currently being handled by: exactly what we need. Unfortunately the Microsoft model doesn’t contain a similar property."


ezért írtam, hogy az IE-ben nincs párja/megfelelője ennek a property-nek

-----------

azt nem tudod véletlenül, hogy egy bizonyos HTML objektummal kapcsolatban lekérdezhetőek-e az őhozzá regisztrált eseménytípusok és eseménykezelő függvények?
arra gondoltam, hogy szülő/gyermek kapcsolatban azonos függvények és eseménytípusok esetén a szülő irányába "tolnám el" az eseménykezelő által végrehajtandó cselekményt

-----------

megnéztem a showProps függvényeddel az IE event objektumának elemeit a kattintás után, de nem találtam gyanús property-t

-----------

meglehet egyébként, hogy teljesen életszerűtlen/akadémikus a problémafeltevésem, mert a gyakorlatban hasonló helyzet nem fordul elő
6

tényleg...

vbence · 2007. Már. 10. (Szo), 22.26
Emlékszem, én is szenvedtem ezzel a dologgal, és most már rélik, mintha tényleg nem lenne megoldás, az a baj, hogy nem emlékszema projektre, amiben volt. De ha van egy kis időm tesztelem egy kicsit a dolgot.
9

megoldás?

teamtom · 2007. Már. 11. (V), 13.53
a régi - egyébként állítólag cross-browser - eseménykezelésnél ez a jelenség nem mutatkozik
obj.onmouseover = function() {
  this.style.backgroundColor = '#fee';
}

...

window.onload = init
lehet, hogy ez butább, kevésbé kifinomult módszer, de működik!

és a két eljárás ráadásul keverhető is, lásd a tesztszkriptemet

ebben a szkriptben a páratlan sorszámú (class="lorem") P-k hátterét a régi, a párosakét (class="ipsum") az új tipusu eseménykezelés módosítja

az első P-ban az EM-nál már nem áll meg az eseménykezelés buborékja!

a második P-ban a STRONG-nál viszont igen, az újabb típusú eseménykezeléssel

tehát a megoldási javaslat: ahol szükség lenne az IE nem létező currentTarget property-jére, használjunk régi tipusu eseménykezelést!

milyen ez a megoldás, lehet gyakorlati haszna?
10

És Jerikó falai leomlanak... :)

vbence · 2007. Már. 11. (V), 18.50
A régi eseménykezeléssel az a baj, hogy csak egyetlen kezelő lehet egy elemen. Ha általános célú függvényket tervezel (mondjuk egy AJAX-os oldal széteffektezésére) ez nem opció.

Ellenben. Sikerült összehekkeljek egy mapEvent függvényt (kompatibilis a Weblaboros addEventtel). Ez egy "emulációs réteget" képez a függvény és a kezelő között. Továbbfejlesztve akár arra is alkalmas lehet, hogy teljesen elrejtse a különböző event objektumok eltéréseit. Talán majd írok belőle egy cikket...

Addig is itt a cucc, ami a currentTarget-et emulálja. (Egy plusz sorral bele lehet tenni, hogy "event.target = event.srcElement", és akkor még egy fokkal könnyebb lesz az élet.)

http://vbence.web.elte.hu/mapevent_demo.html

(Ja, és a Prototype nem csinál ilyet ;)
12

Jerikó

teamtom · 2007. Már. 12. (H), 00.16
Kedves Bence,

Jerikó falai rám omlottak!

egy darabig próbáltam értelmezni a szkriptedet, de be kellett látnom, hogy ez nem az én szintem :(

már itt elakadtam:
30. sor   window.eventMap = {f: new Array(), h: new Array(), e: new Array() };
a window objektumon belül definiálsz - Object Literal módra - egy eventMap objektumot, ami 3 tömböt tartalmaz...

aztán: pl. az arguments.callee property leírását (nem értelmezését!) 5 e-könyvből 1 tartalmazta

segíts kérlek, mert ebből semmit nem fogok tanulni!

kérlek vagy írj - lehetőleg - részletes kommenteket a szkripthez,
vagy írd meg gyorsan azt a cikket a témáról!

------------

hogy érted azt egyébként, hogy "egyetlen kezelő lehet az elemen"?

egy elemhez egy eseménytípusához egy függvényt rendelhetsz, illetve abból a függvényből számtalan másikat meghívhatsz.

dehát ez elég, nem?
(bocs az álnaív kérdésért, de ez a gondjaim egyik forrása: a kérdéseim, problémafelvetésem nem gyakorlati problémák során kerültek elő, hanem a Javascript tudásom elmélyítése közben)

Köszönettel: teamtom
14

Keskeny

vbence · 2007. Már. 12. (H), 01.25
A kérdéses rész, csak egy nyelvi rövidítés (a Javascript valamelyik újabb kiadásából), és ennek felel meg:

window.eventMap = new Array();
window.eventMap.f = new Array();
window.eventMap.h = new Array();
window.eventMap.e = new Array();
ami egy nagyon béna megoldás egy asszociatív konténer létrehozására (ez csak az összedobott verzió a koncepció szemléltetésére).

A lényeg, hogy a 3 tömb (f, h és e) egyazon idexén találhatók az összetartozó adatok: a kezelő függvény amit létrehoztunk, a valódi kezelő függvény, amit majd meg kell hívni és az elem amihez hozzárendeltük (ebből lesz a currentTarget). Kvázi egy objektum 3 mezője.
Az arguments.callee egy reflexiós lehetőség az éppen végehajtott függvényre, és itt találtam: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
A függvény ezzel megkap egy referenciát önmagára. Ezután megkeresi magát az f tömbben (megkapja az indexet), és kiolvassa a másik két tömbből a tárolt adatokat. Így tudja, hogy mit kell beállítani currentTargetnek (hiszen letároltuk, hogy melyik objektumhoz rendeltük a kezelőt), és hogy melyik függvény lesz a user által megadott kezelő (amit meg is hívunk).

A tradícionális eseménykezeléssel egy elem egy eseményéhez egyetlen kezelőt tudsz kapcsolni. Azaz nem tudsz egymástól függetlenül két eszközt használni. (Pl egy rutinkönyvtár felelős a grafikai effektekért, egy másik az adatok frissítéséért, miközben egymásról semmit nem tudnak). Az új eseménykezelés viszont így működik. Ha kétszer hívod meg az addEventListener-t (két külön kezelővel), akkor mindkettő működni fog (addEventListener és nem setEventListener). Ugyanígy az explorerben.
15

Ez miben jobb mint az addEventListener, attachEvent?

Jano · 2007. Már. 12. (H), 11.58
Nem néztem meg részletesen a scriptedet igy kérdezem, hogy miben jobb, más ez mint a meglévő addEventListener és az attachEvent?
16

currentTarget

vbence · 2007. Már. 12. (H), 12.50
Az egész téma a currentTarget megavlósításáról szól IE alatt.
(A currentTarget arra jó, ha tudni szeretnéd, melyik elemben kaptad el az eseményt, nem csak azt, hogy hol keletkezett. Felszálló eseményeknél lényeges.)
7

prototype

wiktor · 2007. Már. 10. (Szo), 23.24
Lehet, hogy nem egy forradalmi ötlet, de nekem bevált, hogy ilyen esetekben amikor a mélyére akarok nézni valaminek, akkor előveszem a prototype-ot, hogy ott hogy oldották meg a kérdéses részt. Ha a prototype tudja amire kiváncsi vagyok, akkor sokkal hamarabb kiderítem, hogy mi a megoldás, mint sok-sok guglizással.
8

prototype

teamtom · 2007. Már. 11. (V), 13.36
ötletnek nem rossz, de engem erre csak a végső kétségbeesés vinne (ott most még nem tartok)

azt hiszem, a prototype túl összetett ahhoz, hogy viszonylag gyorsan ki lehetne "túrni" belőle az én problémámmal kapcsolatos/részben kapcsolatos megoldásokat

ráadásul sokkal jobban kellene értenem hozzá a JS-et

akkor már inkább a moduláris DOMass, bár lehet, hogy elfogult vagyok a karcsúbb megoldásokkal
11

ppk on javascript

Hodicska Gergely · 2007. Már. 12. (H), 00.07
http://www.quirksmode.org/js/introevents.html


Üdv,
Felhő
13

ppk

teamtom · 2007. Már. 12. (H), 00.38
ismerem ezt a sorozatot, ez volt az egyik forrásom, a másik maga a könyv

én nem találtam választ sem itt sem a könyvben arra, hogy az új tipusu eseménykezelésnél miért áll meg a buborék az esemény csomópontján és miért nem megy tovább felfelé egészen addig a csomópontig, ahová maga az eseménykezelő oda van csatolva

ez nekem egészen egyszerűen nem logikus

OK, csinálja meg az eseménykezelést a dokumentumfa egy alsóbb szintjén is, ha ott történik az esemény, de hajtsa végre az általam elvárt csomóponton is, mert én oda csatoltam az eseménykezelőt

miért van az, hogy ennek a szcenáriónak a lekezelésére az Explorernél nem létezik a currentTarget property megfelelője? ostobák talán a Microsoft programozói?
vagy maga a probléma érdektelen, életszerűtlen?

Meg tudnád világítani egy példával, hogy miért nem úgy működik a rendszer, illetve miért rossz az én elképzelésem arról, hogy hogyan kellene működnie?

Köszönettel: teamtom