Search code examples
javascriptreactjseventsdom-eventschildren

How to get as e.target the exact element at which onClick is specified?


I have a React Component and give it onClick event handler:

function Item(props) {
  return <li onClick={props.onClick}>{props.children}</li>
}

Then I use the Component like this:

<Item onClick={ function(e) {console.log(e.target)} }>
  <span>This element is returned as e.target if clicked on it!</span>
</Item>

When I click on the text, the span element is logged as target and when it is clicked outside given span, li element is logged as target.

The problem is:
If there is a lot of child elements inside li element, and id or name are have to be gotten, it becomes a "hacky" task...

The question is:
Is it possible to get inside a handler function as e.target the exact element at which onClick is specified (not it's children; in this case li)?

PS. No jQuery for solution if possible.


Solution

  • event.target will always give you the element, which dispatched the event. In order to get the element who's listener is currently processed, you have to use event.currentTarget.

    This should help: https://developer.mozilla.org/en-US/docs/Web/API/Event/Comparison_of_Event_Targets

    Here is a simple example to illustrated your issue:

    const Inner = () => <div className="inner">Inner</div>
    
    const Outer = () => {
      const clickHandler = e => {
        console.log('target:', e.target.getAttribute('class'));
        console.log('currentTarget:', e.currentTarget.getAttribute('class'));
      };
    
      return (<div className="outer" onClick={clickHandler}><Inner /></div>);
    };
    
    ReactDOM.render(<Outer/>, document.getElementById('app'));
    .outer {
      background: rosybrown;
      padding: 40px;
    }
    
    .inner {
      background: cornsilk;
      padding: 20px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    
    <div id="app"></div>