【问题标题】:jQuery draggable moves when dropped拖放时jQuery可拖动移动
【发布时间】:2015-12-22 17:08:13
【问题描述】:

我已经设置了一个简单的拖放界面,它实现了克隆功能。我遇到的问题是,当元素被拖到主画布上然后放下时,它突然向右移动,而不是准确地放在我拖动它的位置。

这里是javascript:

$(function() {
  var x = null;

  $("#draggable").draggable({
    helper: 'clone',
    cursor: 'move',
    snap: '.snap-target'
  });

  $("#canvas").droppable({
    drop: function(e, ui) {
      if ($(ui.draggable)[0].id != "") {
        x = ui.helper.clone();
        ui.helper.remove();
        x.draggable({
          helper: 'original',
          containment: '#canvas',
          snap: '.snap-target'
        });
        x.appendTo('#canvas');
      }
    }
  });

});

我已经创建了一个 jsfiddle:

https://jsfiddle.net/kuyn6gmc/

如果您尝试将蓝色框拖到主画布中,然后松开鼠标,您将看到框如何“弹出”到右侧。当您在画布内移动框时,它可以正常工作。在小提琴上它并不像在浏览器上全宽那样糟糕,我认为它是相对于视口的总宽度。

如果有人知道为什么会发生这种情况,我将不胜感激:)

谢谢 迈克尔

【问题讨论】:

    标签: javascript jquery css jquery-ui draggable


    【解决方案1】:

    发生这种情况的原因是,可拖动元素在被拖动时相对于视口是绝对定位的。添加元素后,定位是相对于#canvas 元素(因为position: relative),这就是元素在你放下它时移动的原因。

    正如另一个答案所暗示的,您可以从元素中删除position: relative,但是,这可能不会在所有情况下都有效。我建议在添加元素之前考虑元素的位置。

    Updated Example

    例如,您可以减去偏移顶部/左侧定位,以及边框的宽度。这样做,#canvas 元素仍然可以相对定位。

    var canvasOffset = {
      'top': parseInt($(this).offset().top, 10) + parseInt($(this).css('border-top-width'), 10),
      'left': parseInt($(this).offset().left, 10) + parseInt($(this).css('border-left-width'), 10)
    }
    
    $draggble.css({
      "top": parseInt($draggble.css('top'), 10) - canvasOffset.top + 'px',
      "left": parseInt($draggble.css('left'), 10) - canvasOffset.left + 'px'
    }).appendTo('#canvas');
    

    【讨论】:

    • 这应该是公认的答案,因为它还解决了调整视口大小的问题。
    【解决方案2】:

    您必须将position: relative 放入body 而不是canvas

        .draggable { padding: 5px; float: left; margin: 0 10px 10px 0; font-size: .9em; position: relative; }
        .small { border: 1px solid slateblue; width: 115px; height: 115px; background: #c5cae9 }
        .ui-widget-header p, .ui-widget-content p { margin: 0; }
        .text-box { text-align: center; vertical-align: middle; }
        body { font-family: 'Helvetica Neue', Helvetica, Arial, serif; font-size: 13px }
        #canvas { width: 600px; height: 300px; border: 1px solid #cccccc; margin: auto;
            clear: both; }
        .draggable-selectors { margin: 10px auto; width: 1000px; }
        body { position: relative; margin: 0; }
    

    <body class='snap-target'>

    【讨论】:

    • 这确实停止了运动,但不幸的是,快照被搞砸了,所以它们不能紧密贴合在一起,这是我需要发生的,这就是我将相对位置放在画布上的原因。
    • 实际上 - 我只是将相对位置从身体和画布上移开,它可以工作:jsfiddle.net/kuyn6gmc/1
    • snap-target 类放在body 上,而不是canvas 上,并将margin: 0; 也放在上面。我已经更新了答案以反映这一点。
    • 您应该接受 Josh 下面的回答,因为它还解决了调整视口大小的问题。他的方法更好。