Skip to content
Advertisement

Defining listener function inside function

When I define a function outside the function, I cannot access the glide parameter:

export const setFocusListenersForKeyboardNavigation = (glide) => {
    const slides = glide._c.Html.slides;
    for (let i = 0; i < slides.length; i++) {
        const currentSlide = slides[i];
        const slideButton = currentSlide.querySelector(".js-slide-button");
        const slideLink = currentSlide.querySelector(".js-slide-link");
        slideButton && slideButton.addEventListener('focus', focusListener);
        slideLink && slideLink.addEventListener('focus', focusListener);
    }
};

const focusListener = (event) => {
    const activeIndex = glide._i;
    const buttonIndex = event.target.dataset.slideIndex;
    if (activeIndex !== parseInt(buttonIndex)) {
        glide.go(`=${buttonIndex}`);
    }
};

Hence, I have did something like that:

export const setFocusListenersForKeyboardNavigation = (glide) => {
    const focusListener = (event) => {
        const activeIndex = glide._i;
        const buttonIndex = event.target.dataset.slideIndex;
        if (activeIndex !== parseInt(buttonIndex)) {
            glide.go(`=${buttonIndex}`);
        }
    };

    const slides = glide._c.Html.slides;
    for (let i = 0; i < slides.length; i++) {
        const currentSlide = slides[i];
        const slideButton = currentSlide.querySelector(".js-slide-button");
        const slideLink = currentSlide.querySelector(".js-slide-link");
        slideButton && slideButton.addEventListener('focus', focusListener);
        slideLink && slideLink.addEventListener('focus', focusListener);
    }
};

I want to know if it is hack or good practice? Is there more convenient way for doing this.

Advertisement

Answer

Having the function outside is better. Mainly for readability and testing, but if your function is called a lot of times (several hundreds for example) it can be even performance hit to be redefined every time.

you can add arrow function to the listener, that will call the focusListener with the correct parameters. you can do something like this:

export const setFocusListenersForKeyboardNavigation = (glide) => {
    const slides = glide._c.Html.slides;
    for (let i = 0; i < slides.length; i++) {
        const currentSlide = slides[i];
        const slideButton = currentSlide.querySelector(".js-slide-button");
        const slideLink = currentSlide.querySelector(".js-slide-link");
        slideButton && slideButton.addEventListener('focus', (event) => {focusListener(event, glide)});
        slideLink && slideLink.addEventListener('focus', (event) => {focusListener(event, glide));
    }
};

const focusListener = (event, glide) => {
    const activeIndex = glide._i;
    const buttonIndex = event.target.dataset.slideIndex;
    if (activeIndex !== parseInt(buttonIndex)) {
        glide.go(`=${buttonIndex}`);
    }
};
Advertisement