Search code examples
javascriptevent-bubbling

Vanilla JS: Capture wrapping element click, but never its children


I have a div (A) that contains another div (B).

When I click on A, I want e.target to be A. When I click on B, I also want e.target to be A.

Since you must have clicked on the wrapping element to get the inner element, how do you tell JS to never get B?

I know it has something to do with bubbling, but I've thrown everything I can at it and nothing seems to help.

// none of these work
e.preventDefault()
e.stopPropagation()
e.stopImmediatePropagation()
e.cancelBubble = true

// adding { capture: false } doesn't help either

Here's a JSBin reduced test case of the problem. https://jsbin.com/wezoyoyito/1/edit?html,css,js,console,output


Solution

  • Use event.currentTarget instead, which always references the element that the listener is attached to (and not the inner clicked element):

    document.querySelectorAll('.a').forEach(el => {
      el.addEventListener('click', e => {
        console.log(e.currentTarget.className)
      })
    })
    .a {
      background: red;
      width: 100px;
      height: 100px;
    }
    
    .b {
      background: yellow;
      width: 80px;
      height: 80px;
    }
    <div class="a">
      A
      <div class="b">B</div>
    </div>