skip to Main Content

I have an event listener attached to a wrapper element that checks e.target to see if it contains a class im looking for. If it does then the payload of the rest of the callback function goes off. The target is a div inside of a grid and for some reason if you click on the div while moving your mouse too fast, the e.target becomes the grid itself instead of the div I clicked on.

Is there any way to ensure that e.target is the div inside of the grid, instead of the grid, even while moving mouse quickly?

Javascript:

const wrapper = document.querySelector('.wrapper')

wrapper.addEventListener('click', function (e) {
    const btn = e.target.closest(`.myClass`)
    console.log("You selected", e.target.classList.value)
    if (!btn) return
    // callback function stuff
})

HTML:

<div class="wrapper">
    <div class="grid">
        <div class="myClass"></div>
        <div class="myClass1"></div>
        <div class="myClass2"></div>
        <div class="myClass3"></div>
    </div>
</div>

CSS:

.grid {
   display: grid;
   grid-template-columns: 200px 200px;
   grid-template-rows: 200px 200px;
   background-color: white;
  }
.myClass {
   background-color: red;
  }
.myClass1{
   background-color: blue;
  }
.myClass2{
   background-color: green;
  }
.myClass3{
   background-color: yellow;
  }

Fiddle:
https://jsfiddle.net/n2drqv8u/2/

Gif Example of grid being target instead of divs inside of grid when clicking and moving mouse quickly.

2

Answers


  1. i will advice you increase the clickable area of the .myClass div as this might not be large enough and styles like padding, margin, or borders can affect the clickable area
    additionally , use a debounce click event, this way you cwont have issues with rapid clicking or mouse movement (meaning the event handler wont fire until a certain amount of time , which ensures its in the right div)

    function debounce(func, wait) {
        let timeout;
        return function() {
            const context = this, args = arguments;
            clearTimeout(timeout);
            timeout = setTimeout(function() {
                func.apply(context, args);
            }, wait);
        };
    }
    
    const wrapper = document.querySelector('.wrapper');
    
    const handleClick = debounce(function(e) {
        const btn = e.target.closest('.myClass');
        if (!btn) return;
        // Rest of  callback function 
    }, 250); // 250 milliseconds delay
    
    wrapper.addEventListener('click', handleClick);
    
    Login or Signup to reply.
  2. You can just use e.target.classList.contains(). In this example, Div 2 is the only one that contains a class that I am looking for which is .correctDiv

    const grid = document.querySelector(".grid");
    
    grid.addEventListener("click", function(e) {
      if (e.target.classList.contains("correctDiv")) {
        e.target.classList.toggle("highlight");
      }
    });
    .grid {
      display: grid;
      grid-template: repeat(2, 100px) / repeat(2, 100px);
    }
    
    .grid>div {
      background-color: red;
      border: 1px solid black;
      font-size: 2rem;
    }
    
    div.highlight {
      background: green;
    }
    <div class="grid">
      <div>1</div>
      <div class="correctDiv">2</div>
      <div>3</div>
      <div>4</div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search