Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem 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

Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
Když nastavím takto události, var polozky = document.querySelectorAll("#menu > li , #menu2 > li , #…
Kolemjdoucíí 18.01.2020 03:16
Kolemjdoucíí
Ak chceš odstrániť event listener, musíš vedieť jeho referenciu. V kóde, ktorý si skúsil, sa snažíš…
moose 18.01.2020 03:50
moose
const onClick = (event) => new MyClass(event.target)); Funguje to, dík. Tohle mi radil hned na začá… nový
Kolemjdoucíí 18.01.2020 12:27
Kolemjdoucíí
Jenže pokud to pověsím přímo na UL tak to kliknutí reaguje i na volné místa mezi LI. Toto sa ošetru… nový
moose 19.01.2020 22:48
moose
Chová se to nějak divně, pokud kliknu po prvé tak se v constructoru MyClass vypíše console.log('jsem… nový
Kolemjdoucíí 18.01.2020 14:13
Kolemjdoucíí
Ukaž kód. nový
Wikan 18.01.2020 14:45
Wikan
Tady je kód. Položky v seznamech se mění, vytvářejí se nové seznamy a některé seznamy se zase nezobr… nový
Kolemjdoucíí 18.01.2020 16:10
Kolemjdoucíí
const onClick = (event) => new MyClass(event.target); Tohle dej mimo funkci init. Jinak při každém… nový
Wikan 18.01.2020 16:27
Wikan
Díky a jinak je to správně? I to odstranění událostí které nebyly ještě nastavené? nový
Kolemjdoucíí 18.01.2020 16:42
Kolemjdoucíí
Pokud to dělá to, co si od toho představuješ, tak je to "správně". Ale já bych to teda dělal jinak.… nový
Wikan 18.01.2020 16:46
Wikan
Proč těm prvkům nepřiřazuješ listenery hned, jak je vytváříš? jak to myslíš, takto? <li id="m1" on… nový
Kolemjdoucíí 18.01.2020 17:42
Kolemjdoucíí
Ne. Pochopil jsem dobře, že ty elementy vytváříš pomocí JS? Pokud ano, tak jim při vytvoření rovnou… nový
Wikan 18.01.2020 17:48
Wikan
Pochopil jsem dobře, že ty elementy vytváříš pomocí JS? Ano, jenže některé vytvářím pouze jednou -… nový
Kolemjdoucíí 18.01.2020 17:55
Kolemjdoucíí
To je snad jedno kdy. nový
Wikan 18.01.2020 17:58
Wikan
No když nad tím přemýšlím, tak máš pravdu, ok, předělám to. Díky. nový
Kolemjdoucíí 18.01.2020 18:46
Kolemjdoucíí
Prosím tě a co se stane když budu používat opakovaně for (let element of elements) { element.addEv… nový
Kolemjdoucíí 19.01.2020 12:39
Kolemjdoucíí
Pokud to pořád bude ta samá instance onClick, tak nic. nový
Wikan 19.01.2020 12:58
Wikan
To volanie init v konštruktore máš asi navyše. Teraz vždy keď niekto klikne na LI, tak znovu všetko… poslední
moose 19.01.2020 22:53
moose

Když nastavím takto události,

var polozky = document.querySelectorAll("#menu > li , #menu2 > li , #menu3 > li");
for ( var polozka of polozky){
polozka.addEventListener('click', (event) => new MyClass(event.target));
}

jak je zase všechny smažu? Zkoušel jsem tohle - bez výsledku :( Díky

var polozky = document.querySelectorAll("#menu > li , #menu2 > li , #menu3 > li");
for ( var polozka of polozky){
polozka.removeEventListener('click', (event) => new MyClass(event.target));
}

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).

const onClick = (event) => new MyClass(event.target));
// alternatívne:
// function onClick(event) {
//     new MyClass(event.target);
// }

for (let polozka of polozky) {
    polozka.addEventListener('click', onClick);
}

for (let polozka of polozky) {
    polozka.removeEventListener('click', onClick);
}

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.

const onClick = (event) => new MyClass(event.target));

Funguje to, dík. Tohle mi radil hned na začátku Wikan, akorát jsem se k tomu ještě nedostal.

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..

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?

document.body.removeEventListener('click', onClick);

Jenže pokud to pověsím přímo na UL tak to kliknutí reaguje i na volné místa mezi LI.

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.

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();

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <script>
      function init() {
        var elements;
        elements = document.querySelectorAll('#menu-1 > li, #menu-2 > li, #menu-3 > li');
        const onClick = ( event ) => new MyClass ( event . target ) ;
        for (let element of elements) {
          element.removeEventListener('click', onClick);
        } ;
        for (let element of elements) {
          element.addEventListener('click', onClick);
        } ;
      } ;
      class MyClass {
        constructor (event){
          console.log(event.id);
          init();
        } ;
      } ;
    </script>
  </head>
  <body onload="init()">
    <ul id="menu-1">
      <li id="m1">M1</li>
      <li id="m2">M2</li>
      <li id="m3">M3</li>
    </ul>
    <ul id="menu-2">
      <li id="mm1">MM1</li>
      <li id="mm2">MM2</li>
      <li id="mm3">MM3</li>
    </ul>
    <ul id="menu-3">
      <li id="mmm1">MMM1</li>
      <li id="mmm2">MMM2</li>
      <li id="mmm3">MMM3</li>
    </ul>
  </body>
</html>

Prosím tě a co se stane když budu používat opakovaně

        for (let element of elements) {
          element.addEventListener('click', onClick);
        } ;

a nebudu před tím spouštět

        for (let element of elements) {
          element.removeEventListener('click', onClick);
        } ;

Díky

Zpět do poradny Odpovědět na původní otázku Nahoru