使用Jquery UI拖放多个选定的可拖动并恢复无效的拖动

使用光标(套索)绘制一个框将在此JSFiddle示例中选择多个.item

被选中的.item变得.item 。 没有.item.slot是有效的droppable。

当您在多个droppable上放置多个draggable时,只有相应的droppable无效的鼠标所在的.item才会恢复。

如果丢弃无效的 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,'\n 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) })  

HTML:

  

box A

box B

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; } 

您可以使用document.elementFromPoint

更新小提琴

为了删除/恢复原始draggable,我们在drop事件中删除后执行以下操作:

  1. drop事件中检查droppable是否包含.item 。 如果droppable尚未包含.item ,请转到步骤2,否则转到步骤3
  2. 使用css()重置定位后,将元素追加到相应的.slot
  3. 使用animate()方法将元素还原到我们在start事件上使用.data()缓存的上一个位置。

用于删除/恢复被拖动的额外项目:

  • 我们使用document.elementFromPoint找到每个项目的左右可见区域上的元素距离被拖动的元素1px,应该是放置目标 )。

  • 由于没有为这些元素触发实际的drop事件,我们使用draggable的stop事件来检查目标中的任何一个是否是.slot

  • 如果它们中的任何一个是.slot ,这意味着该项目被放置在一个droppable上,我们继续上面提到的step1,否则我们转到step3( 手动将项目还原到它的原始位置


 $(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; } 
    

box A

box B

如果你的意思是,你想要拖放一些东西而你想恢复如果数据被丢弃在错误的区域,那么你可以使用下面的代码作为样本来实现你的目标

 $(function() { $(".connectedSortable").sortable({ connectWith: ".connectedSortable", placeholder: "ui-state-highlight", //containment: "parent", revert: true }); $("#sortable2").sortable({ connectWith: ".connectedSortable", receive: function(event, ui) { if (ui.item.attr('cust-attr') != 'm') { console.log('wrong element'); $("#" + ui.sender.attr('id')).sortable('cancel'); } } }); $("#sortable2x").sortable({ connectWith: ".connectedSortable", receive: function(event, ui) { if (ui.item.attr('cust-attr') == 'm') { console.log('wrong element'); $("#" + ui.sender.attr('id')).sortable('cancel'); } } }); }); 
 #sortable1, #sortable1x, #sortable2, #sortable2x { list-style-type: none; margin: 0; padding: 0 0 2.5em; float: left; margin-right: 10px; } #sortable1 li, #sortable1x li, #sortable2 li, #sortable2x li { box-shadow: 2px 2px 0 #6D6D6D; cursor: pointer; margin: 0 5px 5px 5px; padding: 5px; font-size: 1.2em; width: 150px; } #sortable2 .ui-selecting, #sortable2x .ui-selecting { background: #FECA40; } #sortable2 .ui-selected, #sortable2x .ui-selected { background: #F39814; color: white; } #sortable1x, #sortable2x { list-style-type: none; margin: 0; width: 60%; } 
    
Set 1 :  
  • Item 1 Set 1 X
  • Item 2 Set 1 X
  • Item 3 Set 1 X
  • Item 4 Set 1 X
  • Item 5 Set 1 X
  • Item 1 Set 1 Y
  • Item 2 Set 1 Y
  • Item 3 Set 1 Y
  • Item 4 Set 1 Y
  • Item 5 Set 1 Y
Set 2 :