jQuery 拖放时移动

jQuery draggable moves when dropped

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

这里是 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/

如果您尝试将蓝色方框拖入主 canvas 然后松开鼠标,您将看到方框 "pops" 稍微向右移动。当您在 canvas 内移动框时,它工作正常。在 fiddle 上它不像在浏览器上全宽时那么糟糕,我认为它是相对于视口的总宽度而言的。

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

谢谢 迈克尔

您必须将 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'>

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

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

Updated Example

例如,您可以减去偏移 top/left 定位,以及边框的宽度。这样做,#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');