
JS - Vytvoření třídy v událostech
Ahoj, můžu vytvořit třídu v nějaké události?
Třeba
<button onclick="new myClass()">Click me</button>
popřípadě pokud budu potřebovat objekt tak
<button onclick="obj = new myClass()">Click me</button>
Je to použitelné nebo je to prasárna? Díky
Opět zaměňuješ třídu a objekt. Ale jinak to klidně možné je, jenom bych to nepsal přímo k elementu ale do samostatné funkce.
Děkuji za info..
Nerozumím,
pokud vytvořím novou třídu
var prom = new myClass();
tak proměnná prom je objekt, ne?
Nebo myslíš něco jiného?
Místo tohoto
<button onclick="new myClass()">Click me</button>
použít toto?
<button id="button-1"">Click me</button>
document.getElementById('button-1').addEventListener('click', new myClass);
Ano, je to objekt. A proto je nesmysl psát, že vytváříš novou třídu. Vytváříš nový objekt.
A ne. Myslel jsem to takhle:
Aha, v tom případě se asi nikdy nevytváří nová třída, vždy se vytváří nový objekt, ok.
Jinak tohle ani nefunguje
constructor v té třídě se automaticky spustí po načtení toho kódu ale na kliknutí tlačítka nereaguje.
Požadavky na druhý parametr addEventListener:
document.getElementById('button-1').addEventListener('click', () => new myClass());
Při použití tohoto kódu s parametrem this
vrací v constructoru console.log(event) tohle
a při použití tohoto kódu s parametrem this
vrací v constructoru console.log(event) tohle
Co mám ještě prosím špatně? Děkuji
Prosím tě a tohle je co (event) ? Kam se to předává?
Předpokládám, že tohle (event.target) najdu jako parametr v constructoru a tohle (event) fakt netuším. Dík
Druhý parametr addEventListener je funkce, která jako první parametr přijímá událost (event), na kterou ta funkce reaguje.
Jedna z vlastností události je target, tedy element, kterého se ta událost týká.
Tak zatím moc díky, jdu se tím prokousat.
PS: ještě se zeptám, mají na sebe ty názvy nějakou vazbu?
Jakou vazbu máš na mysli?
Len upresním pár vecí:
- myClass - myClass je trieda. V JavaScripte (a tiež vo väčšine iných jaykov) sa pre názov triedy používa PascalCase konvencia (a nie camelCase), t.j. v tomto prípade by bolo krajšie použiť MyClass.
- new myClass - Predpokladám, že toto si prečítal ako "nová myClass", t.j. "nová trieda". V skutočnosti je to "nový objekt triedy myClass". Tiež to môžeš prečítať ako "nová inštancia (triedy) myClass".
- v novom kóde by som "var" nepoužíval - jedine "const" alebo "let". "var" je dobré maximálne tak pri použití v konzole.
1,2 díky
3 proč ne var?
Technicky nie je s "var" žiaden problém, ale "const" a "let" sú novšie konštrukty so zrozumiteľnejším správaním.
JavaScript je jeden z najpopulárnejších jazykov, hlavne kvôli tomu že v prehliadačoch prakticky neexistuje rozumná alternatíva. Preto ho používa veľa vývojárov na rôznej úrovni od začiatočníkov po pokročilých. Veľa týchto vývojárov nepozná rozdiel medzi "var" (platnosť premennej sa viaže na funkciu) a "let" (platnosť premennej sa viaže na blok). V iných jazykoch je typické, že platnosť premennej sa viaže na blok a tak niektorí vývojári predpokladajú, že "var" sa správa rovnako. Z toho potom vznikajú chyby, ktoré by pri použití "let" nenastali. Použitie "const" robí kód čitateľnejším, pretože hneď vieš, že do danej premennej nebude priradená iná hodnota. Preto je v modernom kóde vo všeobecnosti odporúčané používať všade "const", a v prípade potreby "let".
Když nastavím takto události,
jak je zase všechny smažu? Zkoušel jsem tohle - bez výsledku :( Díky
Ak chceš odstrániť event listener, musíš vedieť jeho referenciu. V kóde, ktorý si skúsil, sa snažíš odstrániť iný event listener, než ktorý bol pridaný (aj keď jeho implementácia vyzerá rovnako).
Obyčajne je lepšie zavesiť obsluhu udalosti priamo na zoznam namiesto na jeho položky, hlavne v prípade, keď je tých položiek veľa (viď google: event delegation). Ja by som napr. dal všetkým tým menu rovnakú CSS triedu a cez addEventListener by som pridal obsluhu iba menu, nie každej položke menu (+ samozrejme upravil príslušnú obsluhu danej udalosti). Pravdepodobne si budeš chcieť ešte pozrieť, na čo sa používa event.currentTarget.
Funguje to, dík. Tohle mi radil hned na začátku Wikan, akorát jsem se k tomu ještě nedostal.
Jenže pokud to pověsím přímo na UL tak to kliknutí reaguje i na volné místa mezi LI.
Proč třeba nefunguje tohle?
Toto sa ošetruje kontrolou v handleri. Ak chceš ošetriť iba kliknutie na LI, tak skontroluješ, že event.target.tagName === 'LI'. Ak máš v LI ešte ďalšie elementy, tak sa ti ale môže stať, že v target budeš mať napr. SPAN, alebo A, alebo iný element. Preto v takom handleri obyčajne chceš najprv získať LI element pomocou funkcie closest (pre podporu IE viď polyfill na danom odkaze). V tvojom konkrétnom prípade, ak by si to chcel robiť použitím event delegation a mať ekvivalentné s tvojim kódom, stačí skontrolovať, že event.currentTarget !== event.target (stále ti zostáva problém s elementami vnorenými v LI).
Chová se to nějak divně,
pokud kliknu po prvé tak se v constructoru MyClass vypíše console.log('jsem tu');
pokud kliknu po druhé tak se v constructoru MyClass vypíše console.log('jsem tu');
pokud kliknu po třetí tak se v constructoru MyClass vypíše 4 x console.log('jsem tu');
pokud kliknu po čtvrté tak se v constructoru MyClass vypíše 8 x console.log('jsem tu');
pokud kliknu po páté tak se v constructoru MyClass vypíše 16 x console.log('jsem tu');
pokud kliknu po šesté tak se v constructoru MyClass vypíše 32 x console.log('jsem tu');
atd...
pokud nastavím onclick každému LI ručně přímo v html, funguje to správně, nechápu.
Ukaž kód.
Tady je kód. Položky v seznamech se mění, vytvářejí se nové seznamy a některé seznamy se zase nezobrazují vždy, proto je v konstruktoru třídy MyClass volání funkce init();
Tohle dej mimo funkci init. Jinak při každém zavolání init() vytváříš ten onClick znovu a když se ho pak snažíš odstranit, tak to nic neudělá, protože je to jiný onClick. I když dělá to samé.
Díky a jinak je to správně? I to odstranění událostí které nebyly ještě nastavené?
Pokud to dělá to, co si od toho představuješ, tak je to "správně". Ale já bych to teda dělal jinak. Proč těm prvkům nepřiřazuješ listenery hned, jak je vytváříš? Dělat to takhle hromadně je sice funkční, ale ne moc hezké ani efektivní.
jak to myslíš, takto?
Ne. Pochopil jsem dobře, že ty elementy vytváříš pomocí JS? Pokud ano, tak jim při vytvoření rovnou přiřaď i listener.
Ano, jenže některé vytvářím pouze jednou - při spuštění stránky.
To je snad jedno kdy.
No když nad tím přemýšlím, tak máš pravdu, ok, předělám to. Díky.
Prosím tě a co se stane když budu používat opakovaně
a nebudu před tím spouštět
Díky
Pokud to pořád bude ta samá instance onClick, tak nic.
To volanie init v konštruktore máš asi navyše. Teraz vždy keď niekto klikne na LI, tak znovu všetko inicializuješ.