Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

158
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!