【问题标题】:drag div on exact mouse point在精确的鼠标点上拖动 div
【发布时间】:2014-07-28 20:29:51
【问题描述】:

我正在尝试仅使用原生 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

【问题讨论】:

    标签: javascript drag-and-drop mouseevent


    【解决方案1】:

    我知道它已经过去了几年,但是在测试 Fiddle 时,我发现(至少对我而言)答案并不完全是 OP 所寻找的。那是因为在响应的 Fiddle 中,div 被完美地移动了,但它总是在它的原点 (0,0) 上移动,而不是在它被点击的地方。

    解决方案其实很简单。

    您正在计算每个mousemove 事件的diff_xdiff_y。但是移动时的鼠标指针位置在mousedown 事件开始时始终相对于 div 是固定的,直到触发mouseup 事件,对吧?因此,只需全局声明差异变量并在 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 的顶部才能触发 @ 987654331@ 事件,然后 e.clientY >= sq.style.tope.clientX >= sq.style.left 将始终为真)。最后一步是将元素移动到精确的鼠标点上。

    此逻辑也可用于其他“拖动事件”,例如 dragstartdrag 事件、touchstarttouchmove 事件以及 pointerdownpointermove 事件(经过一些调整,当然)。所以,由于这种行为可能是相关的,我决定发布这个答案。希望对以后的读者有所帮助。

    这是 OP 修改后的Fiddle

    【讨论】:

      【解决方案2】:

      一个快速的修补程序是:

      改变

      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

      【讨论】:

        猜你喜欢
        • 2013-03-12
        • 2018-05-05
        • 1970-01-01
        • 1970-01-01
        • 2021-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-05
        相关资源
        最近更新 更多