删除不同的拖动后恢复拖动

时间:2016-07-28 17:03:49

标签: jquery-ui draggable jquery-ui-draggable droppable jquery-ui-droppable

我有一个可放置区域的2x2网格[[A,B] [C,D]],网格下面是一个1x4的可拖动网格。我只想要彼此相邻的某些可拖动物。因此,例如,如果B中存在可拖动,并且我将不同的拖动拖动到A中,是否有办法使B中的拖动恢复? draggables有data-row和data-col,这样如果需要,我可以抓住prev / next列中的draggable。

$(".draggable").draggable({
            scroll: false,
            snap: ".snaptarget",
            snapMode: "inner",
            stack: ".draggable",
            revert: function (event, ui) {
                var $draggable = $(this);
                $draggable.data("uiDraggable").originalPosition = {
                    top: 0,
                    left: 0
                };

                return !event;
            }
});

$(".snaptarget").droppable({
            accept: ".draggable",
            drop: function (event, ui) {
                var $draggable = $(ui.draggable);
                var $droppable = $(this);

                // This droppable is taken, so don't allow other draggables
                $droppable.droppable('option', 'accept', ui.draggable);

                ui.draggable.position({
                    my: "center",
                    at: "center",
                    of: $droppable,
                    using: function (pos) {
                        $draggable.animate(pos, "fast", "linear");
                    }
                });

                // Disable prev or next droppable if the pagewidth == 1
                if ($droppable.data("col") == 1) {
                    $droppable.next().droppable("option", "disabled", true);
                    var nextDrag = $(".draggable[data-row='" + $droppable.data("row") + "'][data-col='2']");
                    if (nextDrag.length) {
                        // I need to revert nextDrag if there is one.
                        // I've tried this but it doesn't seem to work
                        nextDrag.data("uiDraggable").originalPosition = {
                           top: 0,
                           left: 0
                        }
                    }
                }
            },
            tolerance: "pointer"
        });

1 个答案:

答案 0 :(得分:1)

做了一点工作,我对偏移和定位从不好。这是关键:

  function returnItem(item, target) {
    // Get Origin
    var oPos = item.data("uiDraggable").originalPosition;
    // Adjust Postion using animation
    item.position({
      my: "top left",
      at: "top left+" + oPos.left,
      of: target,
      using: function(pos) {
        item.animate(pos, "fast", "linear");
      }
    });
  }

以下是基于Draggable Snap to element grid example

的工作示例

https://jsfiddle.net/Twisty/a4ucb6y3/6/

<强> HTML

<div id="target">
  <div class="snaptarget ui-widget-header" data-col="1" data-row="1" style="top: 0; left: 0;">
  </div>
  <div class="snaptarget ui-widget-header" data-col="2" data-row="1" style="top: 0; left: 80px;">
  </div>
  <div class="snaptarget ui-widget-header" data-col="1" data-row="2" style="top: 80px; left: 0;">
  </div>
  <div class="snaptarget ui-widget-header" data-col="2" data-row="2" style="top: 80px; left: 80px;">
  </div>
</div>

<br style="clear:both">

<div id="source">
  <div id="drag-A" class="draggable ui-widget-content" style="left: 0;">
    <p>Drag A</p>
  </div>
  <div id="draggable2" class="draggable ui-widget-content" style="left: 80px;">
    <p>Drag B</p>
  </div>
  <div id="draggable3" class="draggable ui-widget-content" style="left: 160px;">
    <p>Drag C</p>
  </div>
  <div id="draggable4" class="draggable ui-widget-content" style="left: 240px;">
    <p>Drag D</p>
  </div>
</div>

<强> CSS

.draggable {
  width: 80px;
  height: 80px;
  font-size: .9em;
  position: absolute;
  top: 0;
}

.draggable p {
  text-align: center;
  height: 1em;
  margin-top: 30px;
}

#source {
  width: 320px;
  height: 80px;
  position: relative;
}

#target {
  width: 160px;
  height: 160px;
  position: relative
}

.snaptarget {
  width: 80px;
  height: 80px;
  position: absolute;
}

<强>的jQuery

$(function() {
  function returnItem(item, target) {
    // Get Origin
    var oPos = item.data("uiDraggable").originalPosition;
    // Adjust Postion using animation
    di.position({
      my: "top left",
      at: "top left+" + oPos.left,
      of: target,
      using: function(pos) {
        item.animate(pos, "fast", "linear");
      }
    });
  }

  $(".draggable").draggable({
    scroll: false,
    snap: ".snaptarget",
    snapMode: "inner",
    stack: ".draggable",
    revert: "invalid",
    start: function(e, ui) {
      var off = $("#source").position();
      ui.helper.data("uiDraggable").originalPosition = {
        top: ui.position.top,
        left: ui.position.left
      };
    }
  });

  $(".snaptarget").droppable({
    accept: ".draggable",
    drop: function(event, ui) {
      var $draggable = $(ui.draggable);
      var $droppable = $(this);

      // This droppable is taken, so don't allow other draggables
      $droppable.droppable('option', 'accept', ui.draggable);

      // Disable prev or next droppable if the pagewidth == 1
      if ($droppable.data("col") == 1) {
        $droppable.next().droppable("option", "disabled", true);
        var nextDrag = $(".draggable[data-row='" + $droppable.data("row") + "'][data-col='2']");
        if (nextDrag.length) {
          // I need to revert nextDrag if there is one.
          returnItem(nextDrag, $("#source"));
        }
      }
    },
    tolerance: "pointer"
  });
});

在draggable中,当我们开始拖动时,我们想要记录原始位置(以防我们需要稍后恢复)。 revert选项设置为invalid,以防用户将其拖离其他奇怪的位置。

我们将position添加到已拖动项目的data,以便稍后阅读。

当该物品掉落时,魔法就会发生。你已经完成了所有检查,如果它不合适,只需要退回该项目。如果存在nextDrag,我们会将其返回给它。

展望未来,您可能需要考虑在开始/停止事件中追加,克隆和删除元素。就像现在一样,我们实际上只调整元素的位置,而不是DOM中的层次结构。根据您的需求,这可能无关紧要。