在确切的鼠标点上拖动div

时间:2014-07-28 20:29:52

标签: javascript drag-and-drop mouseevent

我尝试使用简单的JavaScript来拖动元素。

当我拖动元素时,我希望它与鼠标指针点击的位置同步移动,我可以通过左上角的元素移动它,这很简单,但是我有问题从准确点移动它点击。

的Javascript

function mouseMove(e){
    if(dragging){
        boxPos(sq,e);
    }
}
function boxPos(el,e){
    box = el.getBoundingClientRect();
    mouse_top = e.clientY;
    mouse_left = e.clientX;
    diff_x = mouse_left - box.left;
    diff_y = mouse_top - box.top;
    el.style.top = (mouse_top + diff_y) +"px";
    el.style.left = (mouse_left + diff_x) +"px";
 }

sq是div,e是事件。

我想要做的是计算鼠标的位置,计算出与左上角的差异并将其添加到左上角,但我得到了不受欢迎的结果。 See fiddle

2 个答案:

答案 0 :(得分:0)

快速修补程序将是:

变化

el.style.top = (mouse_top + diff_y) +"px";
el.style.left = (mouse_left + diff_x) +"px";

el.style.top = (Number(el.style.top.split("px")[0]) + diff_y) +"px";
el.style.left = (Number(el.style.left.split("px")[0]) + diff_x) +"px";

el.style.top = (Number(el.style.top.replace("px", "")) + diff_y) +"px";
el.style.left = (Number(el.style.left.replace("px", "")) + diff_x) +"px";

您需要使用旧坐标和计算的差异将div从旧位置移动到新位置。为了获得旧位置,我使用了当前的topleft设置,从中删除了“px”并将其转换为数字。这是避免字符串连接所必需的(顶部和左侧是字符串值)。

您的程序有另一个错误...您目前无法停止拖动模式。

修改

要删除拖动“停止”错误,您可以从新值中减去1个像素,因此鼠标指针仍然在div内,并且鼠标向上事件将被正确触发。 你可以这样做:

el.style.top = ((Number(el.style.top.replace("px", "")) - 1) + diff_y) +"px";
el.style.left = ((Number(el.style.left.replace("px", "")) - 1) + diff_x) +"px";

这是新的Fiddle

答案 1 :(得分:0)

我知道它已经过去了几年,但是在测试Fiddle时,我发现(至少对我来说)答案并不是OP所要的。这是因为在响应的小提琴中,div完美地移动了,但始终在原点(0,0)上移动,而不是在完全单击的位置移动。

解决方案实际上很简单。

您正在计算每个diff_x事件的diff_ymousemove。但是在移动mousedown事件开始时,鼠标指针的位置始终相对于div是固定的,直到触发mouseup事件为止,对吗?因此,只需全局声明diffs的变量并在mousedown事件中对其进行计算即可。

然后,更改以下代码:

function boxPos(el,e){
   box = el.getBoundingClientRect();
   mouse_top = e.clientY;
   mouse_left = e.clientX;
   diff_x = mouse_left - box.left;
   diff_y = mouse_top - box.top;
   el.style.top = (mouse_top + diff_y) +"px";
   el.style.left = (mouse_left + diff_x) +"px";
}

收件人:

function boxPos(el,e){
   box = el.getBoundingClientRect();
   mouse_top = e.clientY;
   mouse_left = e.clientX;
   el.style.top = (mouse_top - diff_y) +"px";
   el.style.left = (mouse_left - diff_x) +"px";
}

差异的数学是在mousedown事件上完成的,因此我们不再需要它。因此,这将停止闪烁。

此外,由于差异始终为正,因此我们仅从相应的鼠标坐标中减去差异即可放置div,同时考虑了计算出的差异(因为鼠标指针必须位于div上方才能触发{ {1}}事件,那么mousedowne.clientY >= sq.style.top将始终为true)。最后一步是将元素移到准确的鼠标点上的步骤。

此逻辑可用于其他“拖动事件”,例如e.clientX >= sq.style.leftdragstart事件,dragtouchstart事件以及touchmove和{ {1}}事件(当然也要进行一些调整)。因此,由于这种行为可能是相关的,因此我决定发布此答案。希望对以后的读者有所帮助。

这是OP的修改后的Fiddle