Why is clientX reset to 0 on last drag-event and how to solve it?
Asked Answered
M

2

35

I'm trying to drag elements along a line. They should push each other, not cross over or under.

To avoid having a shady element float around on drag, I drag a sub-div which then affects the position of the outer one. Works fine except when you release the mouse which triggers the last drag-event with clientX equal to 0 (see CodePen)!

var b = document.querySelector('.box');
var bi = document.querySelector('.box-inner');
var b2 = document.querySelector('.box2');

bi.addEventListener('dragstart', function() {
  console.log("dragstart")
}, false);

bi.addEventListener('drag', function(event) {
  const bLeft = event.clientX;
  const b2Left = b2.offsetLeft;
  b.style.left = bLeft + "px";
  if (b2Left - 50 <= bLeft) {
    b2.style.left = (bLeft + 50) + "px";
  }

  console.log("drag", event.clientX, event.target.offsetParent.offsetLeft, b2.offsetLeft);

}, false);

bi.addEventListener('dragend', function() {
  console.log("dragend")
}, false);
.box {
  width: 50px;
  height: 50px;
  background-color: hotpink;
  position: absolute;
  top: 0;
  left: 0;
}

.box-inner {
  width: 100%;
  height: 100%;
}

.box2 {
  width: 50px;
  height: 50px;
  background-color: rebeccapurple;
  position: absolute;
  left: 200px;
  top: 0;
}
<div class="box">
  <div class="box-inner" draggable="true"></div>
</div>

<div class="box2"></div>

Why is this and what can I do to avoid resetting it?

Mudfish answered 30/3, 2016 at 12:9 Comment(1)
I tried JSFiddle with somewhat other result. Still wrong, though: jsfiddle.net/ykz1u5osMudfish
S
19

By default, data/elements cannot be dropped in other elements. To allow a drop, you must prevent the default handling of the element when dragover.

document.addEventListener("dragover", function(event) {

  // prevent default to allow drop
  event.preventDefault();

}, false);
Squishy answered 19/9, 2016 at 20:15 Comment(3)
But he does not want to drop the element, nor handle dragover. He just wants drag not to fire with pageX=0 when mouse is released. He is not dragging at that point, so this event should not fire, and even less is he holding mouse at the position pageX=0Lilylilyan
@Lilylilyan while what you're saying is true, his answer does fix the issue.Doreendorelia
Agree with comments above.Dissatisfy
D
6

I just ignore the last event. I don't know why it emits.

// in `drag` event handler
  if (event.screenX === 0) {
    return;
  }

Notice you should use screenX here. When the user zoom in the page, clientX would be a positive value but not zero.

Durr answered 27/4, 2022 at 3:51 Comment(1)
This is the only solution I have come across!Dissatisfy

© 2022 - 2024 — McMap. All rights reserved.