将放置的元素拖回其原始容器

Posted

技术标签:

【中文标题】将放置的元素拖回其原始容器【英文标题】:dragging a dropped element back to its original container 【发布时间】:2018-08-29 03:58:01 【问题描述】:

这就是我到目前为止所拥有的(我正在使用第三方示例)...

 var numbers = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];


  for ( var i=0; i<4; i++ ) 

    $('#card'+numbers[i]).data( 'number', numbers[i] ).draggable( 
      containment: '#content',
      stack: '#cardPile div',
      cursor: 'move',
      snap: '#cardSlots',
    snapMode: 'inner',
    snapTolerance: 10,
       revert:  function(dropped) 
             var $draggable = $(this),
                 hasBeenDroppedBefore = $draggable.data('hasBeenDropped'),
                 wasJustDropped = dropped && dropped[0].id == "droppable";
             if(wasJustDropped) 
                 // don't revert, it's in the droppable
                 return false;
              else 
                 if (hasBeenDroppedBefore) 
                     // don't rely on the built in revert, do it yourself
                     $draggable.animate( top: 0, left: 0 , 'slow');
                     return false;
                  else 
                     // just let the built in revert work, although really, you could animate to 0,0 here as well
                     return true;
                 
             
        
     );
  

  // Create the card slots
  var words = [ 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten' ];
  for ( var i=1; i<=4; i++ ) 
    $('#answer'+words[i-1]).data( 'number', i ).droppable( 
      accept: '#cardPile div',
      activeClass: 'ui-state-hover',
      hoverClass: 'hovered',
      out: function( event, ui ) 
        if (!$(this).attr('id'))
                alert("sdsds") // what i tried here was if there was no droppable container send an alert this doesnt work 
        


      ,
      drop: handleCardDrop
     );
  
function handleCardDrop( event, ui ) 
  var dropdata=   ui.draggable.data('hasBeenDropped',true);
  var slotNumber = $(this).data( 'number' );
  alert($(this).attr('id'))
  var cardNumber = ui.draggable.data( 'number' );
  alert("slot--"+slotNumber);
  alert("cal--"+cardNumber);
alert(dropdata);
  // If the card was dropped to the correct slot,
  // change the card colour, position it directly
  // on top of the slot, and prevent it being dragged
  // again


    ui.draggable.addClass( 'correct' );
   ui.draggable.draggable( 'enable' );
   $(this).droppable( 'enable' );
    ui.draggable.position(  of: $(this), my: 'left top', at: 'left top'  );
    ui.draggable.draggable( 'option', 'revert', false );


问题来了

    如果我将卡从原始容器中拖放到卡槽之外,它会恢复 - 没问题

    如果我将卡从原始容器中拖到卡槽中 - 没问题

    将卡放入插槽后,我希望能够将其拖到多个地块 - 这很有效

    如果我将掉落的卡片拖到屏幕上的任何位置之外,它会粘在我在屏幕上放置的位置,这将失败 - 我希望发生的是,如果我从插槽中拖放一张卡片(已丢弃的卡)它应该发送警报(理想情况下,我要做的是销毁卡并使其重新出现在原始容器上)。这可以吗???

我已经从堆栈中尝试了很多示例,但无法检测到卡何时没有被丢弃在卡槽上...

感谢任何帮助。创建了一个 jsfiddle https://jsfiddle.net/puuaa5r9/5/

谢谢

【问题讨论】:

您能创建一个minimal reproducible example 以便我们试用并帮助您吗? @PraveenKumar jsfiddle.net/puuaa5r9/5 希望对您有所帮助 我已经能够解决这个问题......我应该发布解决方案吗? 是的,这对其他人也有帮助。 【参考方案1】:
  var numbers = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
  //numbers.sort( function()  return Math.random() - .5  );

  for ( var i=0; i<4; i++ ) 
   // alert(i)
    $('#card'+numbers[i]).data( 'number', numbers[i] ).draggable( 
      containment: '#content',
      stack: '#cardPile div',
      cursor: 'move',
      snap: '#cardSlots',
    snapMode: 'inner',
    snapTolerance: 10,
    create: function()$(this).data('position',$(this).position()),
    start:function()$(this).stop(true,true),
       revert:  function(dropped) 
             var $draggable = $(this),
                 hasBeenDroppedBefore = $draggable.data('hasBeenDropped'),
                 wasJustDropped = dropped && dropped[0].id == "droppable";
             if(wasJustDropped) 
                 // don't revert, it's in the droppable
                 return false;
              else 
                 if (hasBeenDroppedBefore) 
                     // don't rely on the built in revert, do it yourself
                     $draggable.animate( top: 0, left: 0 , 'slow');
                     return false;
                  else 
                     // just let the built in revert work, although really, you could animate to 0,0 here as well
                     return true;
                 
             
        
     );
  

  // Create the card slots
  var words = [ 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten' ];
  for ( var i=1; i<=4; i++ ) 
    $('#answer'+words[i-1]).data( 'number', i ).data('droppeditem',"nodrop").droppable( 
      accept: '#cardPile div',
      activeClass: 'ui-state-hover',
      hoverClass: 'hovered',
       over: function(event, ui) 
            $(ui.helper).unbind("mouseup");
        ,

      out:function(event, ui)
            $(ui.helper).mouseup(function() 
                snapToStart(ui.draggable,$(this)); 
            );
        ,
      drop: handleCardDrop
     );
  


function snapToMiddle(dragger, target)
    var topMove = target.position().top - dragger.data('position').top + (target.outerHeight(true) - dragger.outerHeight(true)) / 2;
    var leftMove= target.position().left - dragger.data('position').left + (target.outerWidth(true) - dragger.outerWidth(true)) / 2;
    dragger.animate(top:topMove,left:leftMove,duration:600,easing:'easeOutBack');

function snapToStart(dragger, target)
    dragger.animate(top:0,left:0,duration:600,easing:'easeOutBack');

function handleCardDrop( event, ui ) 
    alert($(ui.droppable).serialize())
 // var dropdata=  
  var slotNumber = $(this).data( 'number' );
  var droppeditem = $(this).data( 'droppeditem' );
  alert($(this).attr('id'))
  var cardNumber = ui.draggable.data( 'number' );
  alert("slot--"+slotNumber);
  alert("cal--"+cardNumber);
  alert("droppeditem--"+droppeditem);


//snapToMiddle(ui.draggable,$(this));


 // if ( droppeditem == "nodrop" ) 
    ui.draggable.addClass( 'correct' );
   ui.draggable.draggable( 'enable' );
   $(this).droppable( 'enable' );
    ui.draggable.position(  of: $(this), my: 'left top', at: 'left top'  );
    ui.draggable.draggable( 'option', 'revert', false );

  /*  ui.draggable.addClass( 'correct' );
   ui.draggable.draggable( 'enable' );
   $(this).droppable( 'enable' );
  ui.draggable.position(  of: $(this), my: 'left top', at: 'left top'  );

   ui.draggable.draggable( 'option', 'revert', true );
    alert("hello2");
  */

  // If all the cards have been placed correctly then display a message
  // and reset the cards for another go




【讨论】:

以上是关于将放置的元素拖回其原始容器的主要内容,如果未能解决你的问题,请参考以下文章

如何将可拖动的元素放入可排序的元素中,放置的项目不是原始元素而是自定义助手

限制原始列表中元素的排序

可拖动元素在缩放 div 上的准确放置

在 jquery drop UI 中,如何使用正确的鼠标位置将拖动元素克隆到放置位置?

使用克隆时可拖动/可放置从原始元素获取数据/属性

让 Dragula 显示悬停在元素上的放置位置