如何使用jQuery Draggable和Droppable实现拖拽功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用jQuery Draggable和Droppable实现拖拽功能相关的知识,希望对你有一定的参考价值。

参考技术A

  第一步:左侧元素可以拖
官方给出的实例是直接在要拖动的元素上添加class="ui-widget-content"。最初我是在所有要拖动的元素都添加了“ui-widget-content”类别。但是测试拖动结果,发现元素只能在它所在的container里面拖动,再往右拖动,div会出现水平或垂直滚动条。不知道是不是自己在参数设置上不对。container设置了overflow:auto。
效果如下图所示:

  因为最终的左侧元素节点是通过Ajax访问后台返回json数据,然后通过javascript动态生成这种结构,而已不能为动态生成的元素绑定drag事件,也就不能调用draggable方法,所以我使用了一个称之“中间拖拽容易元素”,这div一直在页面上。只是默认不显示,只要用户开始拖拽左侧的元素时,它就出现了。当然这里需要自己手动添加很多代码。

  
<div id='draggableDiv' class="ui-widget-content">
        中间拖拽容器元素
    </div>
    <script type="text/javascript">
        $("#draggableDiv").draggable(
            containment: "parent",
            drag: function (event, ui) console.log("拖拽中"); ,
            stop: function () console.log("拖拽结束");
        );
    </script>

  第二步:将要拖的元素内容复制到draggableDiv上。实现拖动父节点时,其下面的子节点元素也要拖放到右边。如果是拖动的子节点元素,就在右边直接显示子节点元素。父节点和子节点是相对的,因为左侧树形结构的节点可以是无限级的,所以一个元素既可能是子节点元素,也会是父节点元素。通过监听鼠标的mousedown和mouseup事件,来判断用户在拖动元素。这步的原理如下图所示:

  当用户拖动B节点时,首先把B元素上的内容复制给draggableDiv元素,当用户拖动B元素,其实是拖动draggableDiv元素。所以我们要计算出我们点击的B元素的位置,然后让draggableDiv在拖动时候显示正确的位置,然后拖动就是draggableDiv元素,用户看起来是拖动的B节点元素。

  第三步:右边的元素可以放到指定的位置上
需要将元素拖到指定的区域里面,然后释放操作。完成“放”的操作。可以从上图看出,我是将元素的上边左边和下边缘的左边存到一个数组里面。然后在“拖”的过程中,一直记录了拖动的左边,放到右侧时,就可以判断当前元素将要放的位置。 
完成代码之后的效果图如下:

draggable jquery get start parent()元素

我想用jquery拖放项目。

现在我有一个包含多个项目的“存储”。

在另一个网站上我有x个盒子。每个盒子只能包含1个项目。

现在,我使用droppable函数在盒子上设置另一个类,只能添加1个盒子,它可用于:

 $( ".droppable" ).droppable({
     accept: ".draggable",
     activeClass: "draghover",
     drop: function( event, ui ) {
         if($( this ).hasClass("droppable")) {
             $( this ).removeClass("droppable").addClass( "droppable-");
         }
     } });

现在,当我将项目移回存储或另一个盒子时,我需要还原类。我用draggable.start函数尝试了这个,但我无法得到正确的父()

$( ".draggable" ).draggable({
        revert: "invalid",
        snap: ".droppable",
        snapMode: "inner",
        start: function( event, ui ) {
            alert($( this ).parent().attr("Class"));

        }
    });

这将始终在第一次拖动之前返回起始位置。不是最新的立场。

存储看起来像:

<td valign="top" class="warenlager" bgcolor="grey" width="200">
    <div class="draggable" class="bild ui-widget-content" id="s73-1">S</div>
    <div class="draggable" class="bild ui-widget-content" id="s74-1">S</div>
</td>

盒子看起来像:

<td><div class="droppable" id="element 2"></div></td>

问候

答案

如果你想在从droppable中删除draggable元素之后恢复该框的类(这是我认为你要求的)然后使用out事件处理程序,所以现在代码看起来像:

 $( ".droppable" ).droppable({
 accept: ".draggable",
 activeClass: "draghover",
 drop: function( event, ui ) {
     if($( this ).hasClass("droppable")) {
         $( this ).removeClass("droppable").addClass( "droppable-");
     }
 },
 out: function()
 {
     $(this).addClass("droppable").removeClass( "droppable-");
 }
 });

希望这可以帮助 :)

另一答案

你可以这样做(通过ES6):

Online demo (jsfiddle)

// Create a class for dragged element
// I will create a new instance form this class when drag
function draggedElement(elementId, parentId) {
  this.id = elementId,
  this.parentId = parentId
};

// Array of dragged elements
// This array use for store dragged elements and their parent's id
var draggedElementList = [];

$('.draggable').draggable({
  start: function(event, ui) {
    // Store or update parent's id  
    updateDraggedElementList($(this).attr("id"), $(this).parent().attr("id"));
  }
});

// This method used for update or store draaged elemens and their parent's id
function updateDraggedElementList(elementId, parentId) {

  // Create new instance
  var element = new draggedElement(elementId, parentId);

  // Check element has already been added or not
  var foundIndex = draggedElementList.findIndex(el => el.id == element.id);
  if (foundIndex > -1)
    draggedElementList[foundIndex] = element;
  else
    draggedElementList.push(element);

  // Print dragged elements and their parents
  printDraggedElements();
}

// I wrote this method for test
function printDraggedElements() {
  for (var i = 0; i < draggedElementList.length; i++) {
    console.log(draggedElementList[i].id);
    console.log(draggedElementList[i].parentId);
  }
}
另一答案

我知道这不是最近的,但是获取可拖动项的父元素的一种方法是在draggable上使用start事件。

$( ".draggable" ).draggable({
    revert: "invalid",
    snap: ".droppable",
    snapMode: "inner",
    start: function( event, ui ) {
        alert(event.currentTarget.parentElement);
    }
});

以上是关于如何使用jQuery Draggable和Droppable实现拖拽功能的主要内容,如果未能解决你的问题,请参考以下文章

如何在一个页面中动态放置多个Droppable来接受不同的Draggable

制作一个包含img draggable的div

前端开发谈谈H5的原生元素拖拽(drap& drop)事件

draggable jquery get start parent()元素

html新特性——拖拽(drag和drop)

IDEA Debug过程中使用Drop Frame或Reset Frame实现操作回退