为什么在最后一个拖动事件中clientX被重置为0,如何解决?

34
我正在尝试沿着一条线拖动元素,它们应该相互推动,而不是相互交叉或穿过。为了避免在拖动时出现阴影元素漂浮的情况,我拖动一个子div然后影响外部元素的位置。这个方法很好,除了当你释放鼠标时会触发最后的拖动事件,其中clientX等于0(参见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>

为什么会这样,我该怎么做才能避免重置?

我尝试了JSFiddle,但结果有些不同。虽然仍然是错误的:https://jsfiddle.net/ykz1u5os/ - primavera133
2个回答

19

默认情况下,数据/元素不能在其他元素中拖放。要允许拖放,必须在dragover时阻止元素的默认处理。

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

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

}, false);

9
但他不想放弃这个元素,也不想处理拖动悬停事件。他只是希望在鼠标松开时,当pageX=0时,拖动不要触发。此时他并没有拖动,因此这个事件不应该被触发,更不用说他是否一直按住鼠标使pageX=0了。 - croraf
3
@croraf所说的是正确的,但他的答案确实解决了这个问题。 - KeironLowe
同意上面的评论。 - undefined

5
我只是忽略了最后一个事件。我不知道为什么它会发出信号。
// in `drag` event handler
  if (event.screenX === 0) {
    return;
  }

请注意在此使用screenX。 当用户放大页面时,clientX将变为正值但不为零。


这是我找到的唯一解决方案! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接