Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

160
Visualizações
Verify with a React Hook if any HTML button is clicked

So I am trying to use an event listener that will trigger the handle only if any button of any type was clicked, regardless of context for the moment.

export const useClickButtonOutside = (ref, handler) => {
  React.useEffect(
    () => {
      const listener = event => {
        // Do nothing if event is not a button
        if (!(event.target instanceof HTMLButtonElement)) {
          return;
        }

        handler(event);
      };

      document.addEventListener('mousedown', listener);
      document.addEventListener('touchstart', listener, { passive: false });

      return () => {
        document.removeEventListener('mousedown', listener);
        document.removeEventListener('touchstart', listener);
      };
    },
   
    [ref, handler]
  );
};

Main issue that is hard to achieve this is:

  1. The event may point to an element that contains a button, but it is technically not an instanceof the html button. e.g. clicking a svg
  2. The hook can applied to different elements of the website, so it should be as dynamic as possible.
about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

To achieve this, you have to take a look at the event path, which will contain all the elements where the event was fired. You need to check if this chain contains a button element, if it does, then handle the event.

export const useClickButtonOutside = (ref, handler) => {
    React.useEffect(() => {
        const listener = (event) => {
            // Do nothing if path contains a button
            let isButton = false;
            event.path.forEach((element) => {
                if (element.tagName === "BUTTON") {
                    isButton = true;
                    return;
                }
            });
            
            if (!isButton) {
                return;
            }

            handler(event);
        };

        document.addEventListener("mousedown", listener);
        document.addEventListener("touchstart", listener, { passive: false });

        return () => {
            document.removeEventListener("mousedown", listener);
            document.removeEventListener("touchstart", listener);
        };
    }, [ref, handler]);
};
about 4 years ago · Juan Pablo Isaza Relatório

0

Can you explain more about the second point?

About the first one, when you click on a button, which has an element inside, you may receive the inside element instead of a button.

For example:

document.querySelector('button').addEventListener('click', e => {
  console.log(e.target);
});
<button>
    <span>Test</span>
</button>

That's because you actually had clicked on the span instead of the button, the button receive the event because of the propagation of the event.

To get the element you can do this:

document.querySelector('button').addEventListener('click', e => {
  console.log(e.target.closest('button'));
});
<button>
    <span>Test</span>
</button>

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda