addEventListener přijímá funkce a (!) objekty

Chcete-li vytvořit interaktivní webová rozhraní, musíte použít události DOM (Document Object Model). Jak to obvykle funguje?

Definujete typ události, který vás zajímá, spárujete jej s funkcí zpětného volání a jste připraveni reagovat na kliknutí, stisknutí kláves, posouvání a mnoho dalších událostí.

Chcete-li například reagovat na kliknutí na tlačítko, lze použít následující kód:

document.querySelector('button')
  .addEventListener('click', () => {
    console.log('element clicked');
  });

Kód se dotáže na DOM, vezme konkrétní prvek a přidá click posluchač událostí pomocí addEventListener .

Podle MDN target.addEventListener definuje následující parametry:

target.addEventListener(type, listener [, options]);
target.addEventListener(type, listener [, useCapture]);
target.addEventListener(type, listener [, useCapture, wantsUntrusted  ]); // Gecko/Mozilla only

addEventListener přijímá typ události, listener funkce zpětného volání a options nebo useCapture parametr.

(Chcete-li se dozvědět více o možných options nebo useCapture přejděte na MDN addEventListener dokumentaci.)

Co kdybych vám řekl, že listener parametr může být funkce, ale že to může být také objekt?

addEventListener a EventListener rozhraní

Ukázalo se, že dokumenty MDN listener takto:

První specifikace událostí DOM (zde mluvíme před HTML5) definovala EventListener rozhraní. Objekty implementující rozhraní (musely definovat handleEvent metoda), kde platí pro použití s ​​addEventListener .

// a class implementing
// the `EventListener` interface
class EventHandler {
  constructor() {
    this.eventCount = 0;
  }

  handleEvent() {
    this.eventCount++;
    console.log(`Event triggered ${this.eventCount} time(s)`);
  }
}

document.querySelector('button')
  .addEventListener('click', new EventHandler());

Výše uvedený kód definuje JavaScriptovou třídu EventHandler . Inicializované objekty obsluhy události lze předat addEventListener reagovat na konkrétní události. Obslužné rutiny událostí pak sledují, kolikrát ke konkrétní události došlo (zkontrolujte to na CodePen). Všechny informace jsou uloženy v samotných objektech a kód funguje bez jakýchkoli proměnných vnějšího rozsahu. Líbí se mi tento vzorec a vidím, že se hodí při práci se sekvenčními událostmi.

Podle MDN EventListener rozhraní je podporováno všemi hlavními prohlížeči a objekty, které jej implementují, můžete bezpečně předat do addEventListener .

Kdy byste předali EventListener objektů na addEventListener ? Rád bych se dozvěděl o dalších příkladech!

Upravit: Někdo sdílel následující úryvek na Redditu.

class MyComponent {
  constructor (el) {
    this.el = el
    this.el.addEventListener('click', this)
  }
  handleEvent (event) {
    console.log('my component element was clicked')
  }
  destroy () {
    this.el.removeEventListener('click', this)
  }
}

const component = new MyComponent(
  document.querySelector('button')
);

MyComponent třída přijímá prvek DOM a automaticky k němu připojuje/odpojuje posluchače událostí. Také implementuje rozhraní EventListener, což znamená, že můžete předat this na addEventListener . Musím říct, že se mi ten vzor líbí!