You need to add event listeners in a method that is guaranteed to fire before the event occurs. However, for optimal loading performance, you should add your event listener as late as possible.
The most common ways to add an event listener:
Declaratively, in your component's template
In the component constructor, for listeners added on the component itself.
In the connectedCallback, for listeners that need to reference DOM outside the component (for example, Window or Document).
After first paint, if you're adding a lot of listeners and first paint performance is critical.
If you need to listen for an event that might occur before your component has been added to DOM, you might need to add the event listener in your component's constructor.
The component constructor is a good place to add event listeners on the host element itself.
If your component adds an event listener to anything except itself or its children–for example, to Window, Document, or some element in the main DOM–you should add the listener in connectedCallback and remove it in disconnectedCallback.
Removing the event listener in disconnectedCallback ensures that any memory allocated by your component will be cleaned up when your component is destroyed or disconnected from the page.
Adding the event listener in connectedCallback (instead of, for example, the constructor or firstUpdated) ensures that your component will re-create its event listener if it is disconnected and subsequently reconnected to DOM.
Sometimes, you may want to defer adding an event listener until after first paint—for example, if you're adding a lot of listeners and first paint performance is critical.
LitElement doesn't have a specific lifecycle callback called after first paint, but you can use this pattern with the firstUpdated lifecycle callback:
firstUpdated fires after the first time your component has been updated and called its render method, but before the browser has had a chance to paint. The Promise/setTimeout line yields to the browser
See firstUpdated in the Lifecycle documentation for more information.
When adding listeners imperatively with addEventListener, you'll need to bind the event listener yourself if you need a reference to the component instance. For example:
When you add an event listener imperatively, using addEventListener, you can specify various event listener options. For example, to use a passive event listener in plain JavaScript you'd do something like this:
Using decorators. Decorators are a proposed JavaScript feature, so you’ll need to use a compiler like Babel or TypeScript to use decorators. See Using decorators for details.
The object passed to eventOptions is used as the options parameter to addEventListener.
If you want to listen to an event fired from a LitElement-based component from within another LitElement or from a lit-html template, you can use the lit-html declarative event syntax:
To listen to events fired from a LitElement-based component in other contexts, like HTML or another framework, use the standard mechanism for listening to DOM events.
In plain HTML and JavaScript, this would be the addEventListener API:
Bubbling events fired from within shadow DOM are retargeted so that, to any listener external to your component, they appear to come from your component itself.