user14638116
user14638116

Reputation:

e.offsetX, e.offsetY reports incorrect number

For some reason when I add the pointer e.offsetX and e.offsetY become inaccurate. This causes the pointer to jump around. Why is this and what can I do to fix it?

theDiv.addEventListener('mousemove', mousemove)

function mousemove(e) {
  pointer.style.top = e.offsetY + 'px'
  pointer.style.left = e.offsetX + 'px'
  console.log(e.offsetX, e.offsetY);
}
#theDiv {
  height: 500px;
  width: 500px;
  background: red;
}

#pointer {
  height: 10px;
  width: 10px;
  background: rgb(255, 255, 255);
  position: absolute;
  border-radius: 50%;
}
<div id="theDiv">
  <div id="pointer"></div>
</div>

Upvotes: 1

Views: 798

Answers (1)

blex
blex

Reputation: 25634

offsetX/Y is calculated relative to the target you're hovering. When the #pointer comes under your mouse, the coordinates are relative to it (hence, small values), so it goes back to the top left, then the offset is high again, so it comes back, and so on.

But you can disable pointer-events on this pointer:

theDiv.addEventListener('mousemove', mousemove)

function mousemove(e) {
  pointer.style.top = e.offsetY + 'px'
  pointer.style.left = e.offsetX + 'px'
  console.log(e.offsetX, e.offsetY);
}
#theDiv {
  height: 500px;
  width: 500px;
  background: red;
}

#pointer {
  height: 10px;
  width: 10px;
  background: rgb(255, 255, 255);
  position: absolute;
  border-radius: 50%;
  pointer-events: none; /* <------------------ */
}
<div id="theDiv">
  <div id="pointer"></div>
</div>

Another way to do it is to use pageX/Y and calculate the offset of #theDiv yourself:

theDiv.addEventListener('mousemove', mousemove)

function mousemove(e) {
  // `this` will always be `#theDiv`
  var rect = this.getBoundingClientRect(),
      offsetX = e.pageX - rect.left,
      offsetY = e.pageY - rect.top;
      
  pointer.style.top = offsetY + 'px';
  pointer.style.left = offsetX + 'px';
  console.log(offsetX, offsetY);
}
#theDiv {
  height: 500px;
  width: 500px;
  background: red;
}

#pointer {
  height: 10px;
  width: 10px;
  background: rgb(255, 255, 255);
  position: absolute;
  border-radius: 50%;
}
<div id="theDiv">
  <div id="pointer"></div>
</div>

Upvotes: 5

Related Questions