Home > Net >  Add eventlistener to nodelist in typescript
Add eventlistener to nodelist in typescript

Time:10-31

I'm trying to add event listener to nodelist with my buttons and toggle class but getting error: Property 'classList' does not exist on type 'EventTarget'.ts(2339)

const tags = document.querySelectorAll('.tags-list__btn');
    
      tags.forEach(el => {
        el.addEventListener('click', (e: Event) => {
          e.preventDefault();
          e.target.classList.add('active');
        });
      });

CodePudding user response:

Just reference the element being iterated over inside the event handler instead of trying to go through the event.

for (const el of document.querySelectorAll('.tags-list__btn')) {
    el.addEventListener('click', (e) => {
        e.preventDefault();
        el.classList.add('active');
    });
}

CodePudding user response:

It's possible to add event listeners to objects that don't match the Element interface, for example document or window. See the EventTarget documentation on MDN for a little more information.

If you know for a fact that your event target will implement the Element interface, then you can use a type assertion to tell TypeScript to narrow its type to Element:

const tags = document.querySelectorAll('.tags-list__btn');

tags.forEach(el => {
    el.addEventListener('click', (e: Event) => {
        e.preventDefault();
        const el = e.target as Element;
        el.classList.add('active');
    });
});

TypeScript playground

If you don't know for certain that your event target implements the Element interface, though, then you should use a type guard instead:

const tags = document.querySelectorAll('.tags-list__btn');

tags.forEach(el => {
    el.addEventListener('click', (e: Event) => {
        e.preventDefault();
        const el = e.target;
        if (el instanceof Element) {
            el.classList.add('active');
        }
    });
});

TypeScript playground

As a side note, if you're binding the exact same event listener to a number of elements, you might want to consider just creating the function once and binding it multiple times instead of using an anonymous function like that. Your current code is creating the same function again each time you're binding it to something, because it's being created inside your forEach loop.

  • Related