Home > Software design >  How to capture "any event" on HTML object?
How to capture "any event" on HTML object?

Time:12-07

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}
      
      onm ouseEnter={(e) =>setTaskbarImage(taskbarAppImageHover)}
      onm ouseLeave={(e) => setTaskbarImage(taskbarAppImage)}
      onm ouseUp={(e) => setTaskbarImage(taskbarAppImageHover)}
      onm ouseDownCapture={(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?

CodePudding user response:

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'),
        onm ouseEnter: () => console.log('onMouseEnter'),
        onm ouseLeave: () => 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>

  • Related