拖放多个选定的可拖动对象并使用 Jquery UI 还原无效的对象 [英] Drag and drop multiple selected draggables and revert invalid ones using Jquery UI

查看:16
本文介绍了拖放多个选定的可拖动对象并使用 Jquery UI 还原无效的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这个JSFiddle中绘制一个带有光标的框(套索)将选择多个.item例子.

选定的 .item 变为可拖动的.里面没有 .item 的空 .slot 是一个有效的 droppable.

当你在多个 droppables 上放置多个 draggables 时,如果对应的 droppable 无效,只有鼠标所在的 .item 会恢复.

如果无效可拖放,如何使所有可拖拽恢复?

Javascript:

$(function () {//我们将在这里存储选定的对象选择的变量 = $([]),总计 = [],偏移 = {顶部:0,左:0};$(document).selectable({过滤器:.item",start: function (event, ui) {//从选择中移除可拖动,否则之前的选择仍然是可拖动的.$(total).draggable("destroy");},selected: function (event, ui) {//将所选推入 total[].total.push(ui.selected)},unselected: function (event, ui) {//console.log('unselect ui: ',ui)u = ui.unselected//从选择[]中删除未选择的.total = jQuery.grep(total, function (n) {返回 n !== u});//console.log('total array (unselected): ',total)},停止:功能(通风口,用户界面){//从total[]中删除重复的元素.jQuery.unique(总计)$(total).each(function () {$(this).draggable(dragOption)})//$(total).draggable(dragOption);//var widget = $( ".selector" ).draggable( "widget" );//console.log('widget: ',widget)console.log('断行---------------------------- ')}});//将拖动选项保存为Obj.拖动选项 = {不透明度:0.45,延迟:300,connectToSortable: ".slot"//,helper: 克隆",距离:5,snap: ".slot",snapMode:内部",回复:无效",开始:功能(事件,用户界面){console.log('可拖动开始 ui: ', ui)选择 = $(total).each(function () {var el = $(this);el.data("偏移量", el.offset())});offset = $(this).offset();//获取相对于文档的坐标},拖动:函数(事件,ui){//console.log(offset.top)var dt = ui.position.top - offset.top,dl = ui.position.left - offset.left;selected.not(this).each(function () {//创建变量,因为我们不需要继续调用 $("this")//el = 我们所在的当前元素//off = 这个元素在被选中时的位置,在拖动之前var el = $(this),off = el.data("偏移量");el.css({顶部:off.top + dt,左:off.left + dl});});},停止:功能(事件,用户界面){console.log('拖动停止 ui : ', ui)}};//将放置选项保存为Obj.dropOption = {接受:'.item',下降:功能(事件,用户界面){console.log('丢弃事件:', 事件);console.log('删除用户界面:', 用户界面)},activate: function (event, ui) {//console.log('this : ',this,'
 ui : ',ui)},out: function (event, ui) {//console.log('out',$(this))},停用:功能(事件,用户界面){//console.log('停用')},容差:相交",instance: function (event, ui) {//console.log('instance ui : ',ui)},over: function (event, ui) {//console.log('this item : ',ui.draggable[0],'on this slot: ',this)},活动类:green3"}//使空槽可放置$(".slot:not(:has(>div))").droppable(dropOption)}) <!--文档准备就绪-->

HTML:

<div id="容器"><div id="header"></div><div class="box" id="boxA"><h4>框A</h4>

<div class="item" id="a1"></div>

<div class="item" id="a2"></div>

<div class="item" id="a3"></div>

<div class="slot" id="A4"></div><div class="slot" id="A5"></div>

<div class="box" id="boxB"><h4>框B</h4><div class="slot" id="B1"></div><div class="slot" id="B2"><div class="item" id="b2"></div>

<div class="slot" id="B3"></div><div class="slot" id="B4"></div><div class="slot" id="B5"><div class="item" id="b5"></div>

CSS:

文档{背景颜色:#FFF;}.盒子 {高度:180px;向左飘浮;边框顶部宽度:5px;边框右宽度:5px;边框底部宽度:5px;边框左宽度:5px;边框顶部样式:实心;边框右样式:实心;边框底部样式:实心;左边框样式:实心;边框顶部颜色:#999;边框右颜色:#999;边框底部颜色:#999;左边框颜色:#999;宽度:150px;文本对齐:居中;左边距:100px;}.物品 {位置:绝对;字体大小:12px;高度:14px;背景颜色:#CCC;宽度:110px;文字装饰:无;字体系列:Arial、Helvetica、sans-serif;颜色:#999;左边距:6px;文本对齐:居中;}#页眉页脚 {向左飘浮;高度:200px;宽度:100%;}.投币口{边框顶部宽度:1px;边框右宽度:1px;边框底部宽度:1px;边框左宽度:1px;边框顶部样式:虚线;边框右样式:虚线;边框底部样式:虚线;左边框样式:虚线;高度:15px;宽度:120px;边距顶部:2px;文本对齐:居中;垂直对齐:中间;行高:90px;右边距:自动;左边距:自动;}.ui-选择{背景:#FECA40;}.ui 选择 {背景色:#F90;}.green3 {背景颜色:#D9FFE2;}

解决方案

您可以使用 document.elementFromPoint.

更新小提琴

为了删除/恢复原始可拖动对象,我们在将其放入 drop<后执行以下操作/a> 事件:

  1. 中检查droppable是否包含.itemdrop 事件.如果 droppable 尚未包含 .item,请转到第 2 步,否则转到第 3 步
  2. append() 重置定位后的元素到对应的.slot使用 css()
  3. 使用 animate() 方法将元素恢复到我们之前的位置使用 .data() 缓存在 start 事件.

用于删除/还原被拖动的额外项目:

<小时>

$(function() {var dragOption = {延迟:10,距离:5,不透明度:0.45,回复:无效",恢复持续时间:100,开始:功能(事件,用户界面){$(".ui-selected").each(function() {$(this).data("原始", $(this).position());});},拖动:功能(事件,用户界面){var offset = ui.position;$(".ui-selected").not(this).each(function() {var current = $(this).offset(),targetLeft = document.elementFromPoint(current.left - 1, current.top),targetRight = document.elementFromPoint(current.left + $(this).width() + 1, current.top);$(this).css({位置:相对",左:偏移量.左,顶部:偏移量.top}).data("target", $.unique([targetLeft, targetRight]));});},停止:功能(事件,用户界面){$(".ui-selected").not(this).each(function() {var $target = $($(this).data("target")).filter(function(i, elm) {返回 $(this).is(".slot") &&!$(this).has(".item").length;});如果($target.length){$target.append($(this).css({顶部:0,左:0}))} 别的 {$(this).animate({顶部:0,左:0}, 慢的");}});$(".ui-selected").data("original", null).data(目标",空).removeClass("ui-selected");}},dropOption = {接受:'.item',activeClass: "green3",下降:功能(事件,用户界面){if ($(this).is(".slot") && !$(this).has(".item").length) {$(this).append(ui.draggable.css({顶部:0,左:0}));} 别的 {ui.draggable.animate({顶部:0,左:0}, 50);}}}$(".box").selectable({过滤器:.item",开始:功能(事件,用户界面){$(".ui-draggable").draggable("destroy");},停止:功能(事件,用户界面){$(".ui-selected").draggable(dragOption)}});$(".slot").droppable(dropOption);});

.box {向左飘浮;宽度:150px;高度:180px;文本对齐:居中;左边距:20px;边框:5px 实心 #999;}.投币口 {位置:相对;宽度:120px;高度:15px;边距顶部:2px;边距:0 自动;边框:1px 虚线;}.物品 {宽度:110px;高度:14px;边距:0 自动;z-索引:1;背景颜色:#CCC;}.ui-选择{背景:#FECA40;}.ui 选择 {背景色:#F90;}.green3 {背景颜色:#D9FFE2;}

<link href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" rel="样式表"/><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script><div id="容器"><div id="boxA" class="box"><h4>框A</h4><div id="A1" class="slot"><div id="a1" class="item"></div>

<div id="A2" class="slot"><div id="a2" class="item"></div>

<div id="A3" class="slot"><div id="a3" class="item"></div>

<div id="A4" class="slot"></div><div id="A5" class="slot"></div>

<div id="boxB" class="box"><h4>框B</h4><div id="B1" class="slot"></div><div id="B2" class="slot"><div id="b2" class="item"></div>

<div id="B3" class="slot"></div><div id="B4" class="slot"></div><div id="B5" class="slot"><div id="b5" class="item"></div>

<小时>

其他参考:

<小时>

P.S:这仅在可拖动小于可放置时才有效(在这种情况下是正确的)

Drawing a box with cursor (lasso) will select multiple .item in this JSFiddle example.

Selected .item's become draggable. Empty .slot without an .item inside is a valid droppable.

When you drop multiple draggables on multiple droppables, only the .item which mouse is on will revert if its corresponding droppable not valid.

How to make every draggable revert if it's dropped on invalid droppable?

Javascript:

$(function () {
  // we are going to store the selected objects in here
  var selected = $([]),
    total = [],
    offset = {
        top: 0,
        left: 0
    };

  $(document).selectable({
    filter: ".item",
    start: function (event, ui) { //remove draggable from selection, otherwise previous selection will still be draggable. 
        $(total).draggable("destroy");
    },
    selected: function (event, ui) { // push selected into total[].
        total.push(ui.selected)
    },
    unselected: function (event, ui) { //console.log('unselect ui: ',ui)
        u = ui.unselected
        //remove unselected from selection[].
        total = jQuery.grep(total, function (n) {
            return n !== u
        });
        //console.log('total array (unselected): ',total)
    },
    stop: function (vent, ui) {
        //remove duplicated element from total[].
        jQuery.unique(total)
        $(total).each(function () {
            $(this).draggable(dragOption)
        })
        //$(total).draggable(dragOption);
        //var widget = $( ".selector" ).draggable( "widget" );
        //console.log('widget: ',widget)
        console.log('break line---------------------------- ')
    }

  });

  //save drag option as an Obj.
  dragOption = {
    opacity: 0.45,
    delay: 300,
    connectToSortable: ".slot"
    //,helper: "clone"
    ,
    distance: 5,
    snap: ".slot",
    snapMode: "inner",
    revert: "invalid",
    start: function (event, ui) {
        console.log('draggable start ui: ', ui)
        selected = $(total).each(function () {
            var el = $(this);
            el.data("offset", el.offset())
        });
        offset = $(this).offset(); //get coordinates relative to document
    },
    drag: function (event, ui) { //console.log(offset.top)
        var dt = ui.position.top - offset.top,
            dl = ui.position.left - offset.left;
        selected.not(this).each(function () {
            // create the variable for we don't need to keep calling $("this")
            // el = current element we are on
            // off = what position was this element at when it was selected, before drag
            var el = $(this),
                off = el.data("offset");
            el.css({
                top: off.top + dt,
                left: off.left + dl
            });
        });
    },
    stop: function (event, ui) {
        console.log('drag stop ui : ', ui)
    }
  };

  //save drop option as an Obj.
  dropOption = {
    accept: '.item',
    drop: function (event, ui) {
        console.log('drop event : ', event);
        console.log('drop ui : ', ui)
    },
    activate: function (event, ui) { //console.log('this : ',this,'
 ui : ',ui)
    },
    out: function (event, ui) { //console.log('out',$(this))
    },
    deactivate: function (event, ui) { //console.log('deactivate')
    },
    tolerance: "intersect",
    instance: function (event, ui) { //console.log('instance ui : ',ui)
    },
    over: function (event, ui) { //console.log('this item : ',ui.draggable[0],'on this slot: ',this)
    },
    activeClass: "green3"

}
  // make empty slot droppable
  $(".slot:not(:has(>div))").droppable(dropOption)
}) <!--doc ready-->

HTML:

<body>
  <div id="container">
    <div id="header"></div>
    <div class="box" id="boxA">
      <h4>box A</h4>
      <div class="slot" id="A1">
        <div class="item" id="a1"></div>
      </div>
      <div class="slot" id="A2">
        <div class="item" id="a2"></div>
      </div>
      <div class="slot" id="A3">
        <div class="item" id="a3"></div>
      </div>
      <div class="slot" id="A4"></div>
      <div class="slot" id="A5"></div>
    </div>
    <div class ="box" id="boxB">
      <h4>box B</h4>
      <div class="slot" id="B1"></div>
      <div class="slot" id="B2">
        <div class="item" id="b2"></div>
      </div>
      <div class="slot" id="B3"></div>
      <div class="slot" id="B4"></div>
      <div class="slot" id="B5">
        <div class="item" id="b5"></div>
      </div>
    </div>
  </div> 
</body>

CSS:

document {
    background-color: #FFF;
}

.box {
    height: 180px;
    float: left;
    border-top-width: 5px;
    border-right-width: 5px;
    border-bottom-width: 5px;
    border-left-width: 5px;
    border-top-style: solid;
    border-right-style: solid;
    border-bottom-style: solid;
    border-left-style: solid;
    border-top-color: #999;
    border-right-color: #999;
    border-bottom-color: #999;
    border-left-color: #999;
    width: 150px;
    text-align: center;
    margin-left: 100px;
}
.item {
    position: absolute;
    font-size: 12px;
    height: 14px;
    background-color: #CCC;
    width: 110px;
    text-decoration: none;
    font-family: Arial, Helvetica, sans-serif;
    color: #999;
    margin-left: 6px;
    text-align: center;
}

#header, #footer {
    float: left;
    height: 200px;
    width: 100%;
}
.slot{
    border-top-width: 1px;
    border-right-width: 1px;
    border-bottom-width: 1px;
    border-left-width: 1px;
    border-top-style: dotted;
    border-right-style: dotted;
    border-bottom-style: dotted;
    border-left-style: dotted;
    height: 15px;
    width: 120px;
    margin-top: 2px;
    text-align: center;
    vertical-align: middle;
    line-height: 90px;
    margin-right: auto;
    margin-left: auto;
    }
.ui-selecting {
    background: #FECA40;
  }
.ui-selected {
    background-color: #F90;
  }
.green3 {
    background-color: #D9FFE2;
}

解决方案

You can make use of document.elementFromPoint.

Updated Fiddle

For dropping/reverting the original draggable, we do the following once it is dropped in drop event:

  1. Check whether the droppable contains an .item or not in the dropevent. If the droppable doesn't already contain an .item, Go to step 2, else go to step3
  2. append() the element to corresponding .slot after resetting the positioning using css()
  3. Revert the element using animate() method to previous position which we cached using .data() on start event.

For dropping/reverting the extra items being dragged:


$(function() {

  var dragOption = {
      delay: 10,
      distance: 5,
      opacity: 0.45,
      revert: "invalid",
      revertDuration: 100,
      start: function(event, ui) {
        $(".ui-selected").each(function() {
          $(this).data("original", $(this).position());
        });
      },
      drag: function(event, ui) {
        var offset = ui.position;
        $(".ui-selected").not(this).each(function() {
          var current = $(this).offset(),
            targetLeft = document.elementFromPoint(current.left - 1, current.top),
            targetRight = document.elementFromPoint(current.left + $(this).width() + 1, current.top);
          $(this).css({
            position: "relative",
            left: offset.left,
            top: offset.top
          }).data("target", $.unique([targetLeft, targetRight]));
        });
      },
      stop: function(event, ui) {
        $(".ui-selected").not(this).each(function() {
          var $target = $($(this).data("target")).filter(function(i, elm) {
            return $(this).is(".slot") && !$(this).has(".item").length;
          });
          if ($target.length) {
            $target.append($(this).css({
              top: 0,
              left: 0
            }))
          } else {
            $(this).animate({
              top: 0,
              left: 0
            }, "slow");
          }

        });
        $(".ui-selected").data("original", null)
          .data("target", null)
          .removeClass("ui-selected");
      }
    },
    dropOption = {
      accept: '.item',
      activeClass: "green3",
      drop: function(event, ui) {
        if ($(this).is(".slot") && !$(this).has(".item").length) {
          $(this).append(ui.draggable.css({
            top: 0,
            left: 0
          }));
        } else {
          ui.draggable.animate({
            top: 0,
            left: 0
          }, 50);
        }
      }
    }

  $(".box").selectable({
    filter: ".item",
    start: function(event, ui) {
      $(".ui-draggable").draggable("destroy");
    },
    stop: function(event, ui) {
      $(".ui-selected").draggable(dragOption)
    }
  });
  $(".slot").droppable(dropOption);
});

.box {
  float: left;
  width: 150px;
  height: 180px;
  text-align: center;
  margin-left: 20px;
  border: 5px solid #999;
}
.slot {
  position: relative;
  width: 120px;
  height: 15px;
  margin-top: 2px;
  margin: 0 auto;
  border: 1px dotted;
}
.item {
  width: 110px;
  height: 14px;
  margin: 0 auto;
  z-index: 1;
  background-color: #CCC;
}
.ui-selecting {
  background: #FECA40;
}
.ui-selected {
  background-color: #F90;
}
.green3 {
  background-color: #D9FFE2;
}

<link href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<div id="container">
  <div id="boxA" class="box">
    <h4>box A</h4>

    <div id="A1" class="slot">
      <div id="a1" class="item"></div>
    </div>
    <div id="A2" class="slot">
      <div id="a2" class="item"></div>
    </div>
    <div id="A3" class="slot">
      <div id="a3" class="item"></div>
    </div>
    <div id="A4" class="slot"></div>
    <div id="A5" class="slot"></div>
  </div>
  <div id="boxB" class="box">
    <h4>box B</h4>

    <div id="B1" class="slot"></div>
    <div id="B2" class="slot">
      <div id="b2" class="item"></div>
    </div>
    <div id="B3" class="slot"></div>
    <div id="B4" class="slot"></div>
    <div id="B5" class="slot">
      <div id="b5" class="item"></div>
    </div>
  </div>
</div>


Other references:


P.S: This will only work if the draggable is smaller than droppable (Which is true in this case)

这篇关于拖放多个选定的可拖动对象并使用 Jquery UI 还原无效的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆