How to capture "any event" on HTML object?

How to capture "any event" on HTML object?

Problem Description:

I have several HTML img element I want to manipulate on the following events:

onMouseEnter
onMouseLeave
onMouseDownCapture
onMouseUp

A naive solution (that works) is to implement these listeners for each event manually as such:

   <img 
      src={taskbarImage}
      
      onMouseEnter={(e) =>setTaskbarImage(taskbarAppImageHover)}
      onMouseLeave={(e) => setTaskbarImage(taskbarAppImage)}
      onMouseUp={(e) => setTaskbarImage(taskbarAppImageHover)}
      onMouseDownCapture={(e) => setTaskbarImage(taskbarAppImageFocus)}

      className="taskbar-application-img">
   </img>

This code is kind of messy and I would much rather simply attach one function that triggers any time any event happens on the tag. After this, the function would then analyze for what event it is and act appropriately. Something like this:

const taskBarManipulation = (e) => {
  switch (e.type) {
    case "mouseenter":
      setTaskbarImage(taskbarAppImageHover);
    case "mouseleave":
      setTaskbarImage(taskbarAppImageHover);
    case "mouseup":
      setTaskbarImage(taskbarAppImage);
    case "mousedowncapture":
      setTaskbarImage(taskbarAppImageFocus);
  }
};

The snippet above works for detecting the type of event and changing the variable. However, I don’t know how to make the function trigger on any event happening in the tag. Any suggestions?

Solution – 1

There are many events, listening tho all of those will slow down your component, and is not recommended.


I’d use a function that returns the eventListeners you wish to add, and then apply that to the component using spreading:

const { useState } = React;

const getEvents = () => {
    return {
        onClick: () => console.log('onClick'),
        onMouseEnter: () => console.log('onMouseEnter'),
        onMouseLeave: () => console.log('onMouseLeave'),
        // ...etc
    };
}

const Example = () => {
    return (
        <div>
            <h1 {...getEvents()}>{'Test me!'}</h1>
        </div>
    )
}
ReactDOM.render(<Example />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>

If all those event have the same handler, we can create a more fancy getEvents function like so:

const eventHandler = (e) => console.log(e.type);

const getEvents = (events = [ 'onClick', 'onMouseEnter', 'onMouseLeave' ]) => {
    return events.reduce((c, p) => ({ ...c, [p]: eventHandler }), {});
}
const { useState } = React;

const eventHandler = (e) => console.log(e.type);

const getEvents = (events = [ 'onClick', 'onMouseEnter', 'onMouseLeave' ]) => {
    return events.reduce((c, p) => ({ ...c, [p]: eventHandler }), {});
}

const Example = () => {
    return (
        <div>
            <h1 {...getEvents()}>{'Test me!'}</h1>
        </div>
    )
}
ReactDOM.render(<Example />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Rate this post
We use cookies in order to give you the best possible experience on our website. By continuing to use this site, you agree to our use of cookies.
Accept
Reject