可拖动的 droppable 和 sortable

Posted

技术标签:

【中文标题】可拖动的 droppable 和 sortable【英文标题】:draggable droppable with sortable 【发布时间】:2018-05-15 10:15:29 【问题描述】:

我们试图集成多个 drggable 和 droppable。在这种情况下,我们使用 sortable 来简化克隆功能。拖放后可拖动需要再次拖动。

我们如何将 sortable 限制为仅接收一个元素并在多个元素落入时恢复为原始元素。

在这种情况下,sortable 的过度功能看起来行为不端。

注释行代码用于禁用在可排序上删除第二个元素。这没有按预期工作。

启用我的注释代码时的两个问题:

    从 droppable 移出后,可拖动克隆不会恢复到原始位置。 draggable 元素从一个 droppable 移动到另一个可恢复到 draggable 的原始位置。

如需演示,请参阅 this jsfiddle

脚本:

//  jQuery.noConflict();

jQuery( document ).ready(function()  init(););
function init() 

  var mouse_button = false;
  jQuery('.ui-draggable').live(
      mousedown: function () 
          mouse_button = true;
      ,
      mouseup: function () 

          if (jQuery(this).attr('data-pos') == 'out' && jQuery(this).attr('data-id')) 
              var p = jQuery('#' + jQuery(this).attr('data-id'));
              var offset = p.offset();
              jQuery(this).hide();
              jQuery(this).animate( left: offset.left, top: offset.top, width: jQuery(this).width, height: jQuery(this).height , 100, function () 
                  jQuery(this).remove();
                  $( ".ui-droppable" ).each(function() 
                    if($(this).children().length == 0) 
                      $( this ).removeClass("dontDrop");
                    
                  );
                  //if(p[0].hasAttribute("draggable"))
                  p.draggable("enable");

             //     $('.ui-droppable').sortable('option', 'connectWith',$('.ui-droppable').not('.dontDrop'));
             //     $('.ui-draggable').draggable('option', 'connectToSortable',$('.ui-droppable').not('.dontDrop'));

              );
          
          mouse_button = false;
      ,
      mouseout: function () 
          if (mouse_button) 
              mouse_button = false;
          
      

  );

    jQuery( '.ui-draggable' ).draggable( 
      cursor: 'move',
      helper: 'clone',
      connectToSortable: ".ui-droppable",
      revert: function (event, ui) 
        
     );


    jQuery(".ui-droppable").sortable(
        cursor: "move",
        connectWith: ".ui-droppable",
        receive: function (event, ui) 

        if($(this).children().length >= 1) 

            $(this).children().addClass('filled');
            $(this).addClass('dontDrop');

            $( ".ui-droppable" ).each(function() 
              if($(this).children().length == 0) 
                $( this ).removeClass("dontDrop");
              
            );
       //     $('.ui-droppable').sortable('option', 'connectWith',$('.ui-droppable').not('.dontDrop'));
       //     $('.ui-draggable').draggable('option', 'connectToSortable',$('.ui-droppable').not('.dontDrop'));
        else 
            $(this).children().removeClass('filled');
        
        if (jQuery(this).data().sortable.currentItem) 
                jQuery(this).data().sortable.currentItem.attr('data-id', jQuery(ui.item).attr("id"));
               // if(jQuery(ui.item)[0].hasAttribute("draggable"))
                jQuery(ui.item).draggable("disable");
            

        ,
        out: function (event, ui)   if (ui.helper)  ui.helper.attr('data-pos', 'out');  ,
        over: function (event, ui)  ui.helper.attr('data-pos', 'in'); 
    );

  

【问题讨论】:

您输入了:“启用注释代码后三件事无法正常工作”,但该行后面的列表只有两个列表项 - 应该有第三个吗? 目前还不清楚您要完成什么。我不会使用.droppable(),除了使用.sortable(),就像你在小提琴中一样。不清楚的是顺序和状态。如果我将“Test 1”拖到一个正方形上,究竟会发生什么? 另外,在您的代码中,您从jQuery() 切换到$(),我认为这会给您带来问题。 用于代码清理和查看更简洁功能的初始通道。 jsfiddle.net/Twisty/7mmburcx/30 仍然不清楚您要达到的目标。 【参考方案1】:

这是一个工作示例:click here

您可以使用 Jquery 的 draggable 和 droppable 交互来实现您想要的。检查工作示例。

$(document).ready(function () 

  $(".ui-draggable").draggable(draggable_options) //make cards draggable

  $(".ui-droppable").droppable( //handle card drops
    greedy: true,
    drop: function (event, ui) 
      handleDrop(this, event, ui)
    ,
    accept: function () 
      return checkIfShouldAcceptTheDraggable(this)
    
  )
)

【讨论】:

我们需要的两件事就是为什么使用可排序的。当拖出任何 droppable 时,它​​应该返回到其原始位置(在顶部列表中)。另一种是在放置在任何droppable上时禁用原始元素,当释放到外部时,它应该返回到原始位置并激活它。 我编辑了答案以包含新功能。请不要忘记标记为已接受。【参考方案2】:

你可以这样做:(Online Demo (fiddle))

var draggable_options = 
  helper: 'clone',
  cursor: 'move',
  revert: 'invalid',
;

$(".ui-draggable").draggable(draggable_options);

$(".ui-droppable").droppable(
  drop: function(event, ui) 
    var $item = ui.draggable;
    $item.draggable(draggable_options)
    $item.attr('style', '')
    $(this).append($item)
  ,
  accept: function() 
    return $(this).find("li").length === 0 // Your condition
  
);

$(".textToImageRightPanel").droppable(
  drop: function(event, ui) 
    var $item = ui.draggable;
    $item.draggable(draggable_options);
    $item.attr('style', '');
    // Return to older place in list
    returnToOlderPlace($item);
  
);

// Return item by drop in older div by data-tabidx
function returnToOlderPlace($item) 
  var indexItem = $item.attr('data-tabidx');
  var itemList = $(".textToImageRightPanel").find('li').filter(function() 
    return $(this).attr('data-tabidx') < indexItem
  );
  if (itemList.length === 0)
    $("#cardPile").find('ul').prepend($item);
  else
    itemList.last().after($item);

【讨论】:

如上所述,我们不想从上面的栏中删除元素,而是禁用它。拖出时也应返回顶部框位置。【参考方案3】:

最好使用revert: function().draggable() 中确定何时恢复。

功能: 确定元素是否应恢复到其起始位置的功能。该函数必须返回 true 才能恢复元素。

你可以这样做:

  jQuery('.ui-draggable').draggable(
    cursor: 'move',
    helper: 'clone',
    connectToSortable: ".ui-droppable",
    revert: function(item) 
      if (!item) 
        return true;
       else 
        if (item.hasClass("dontDrop")) 
          return true;
        
      
      return false;
    
  );

如果不接受可拖动项目,则通过false 恢复函数。例如,如果它掉在不是目标的东西上。如果接受了可拖动项,则返回一个 jQuery 对象。

查看更多:jQueryUI sortable,draggable revert event

逻辑有点混乱。如果传回的是false,我们将true返回到revert,让可拖动的项目恢复到它的位置。如果传回的不是false,那么它就是我们可以测试的对象。如果目标是“满的”,我们就还原。否则我们不会还原。

Sortable 出于某种原因仍想添加该项目。可能需要调整到update 并清除所有不属于"filled" 类的项目。

小提琴:https://jsfiddle.net/Twisty/7mmburcx/32/

【讨论】:

以上是关于可拖动的 droppable 和 sortable的主要内容,如果未能解决你的问题,请参考以下文章

jquery UI droppable 和 sortable 不起作用?

如何使 jQuery UI droppable hoverClass 仅适用于可拖动对象?

jQuery UI Droppable and Sortable - 放置在正确的排序位置

在 droppable 的 Drop 事件上调用 $(item).sortable('cancel') 会禁用可排序

Jquery 可拖动/可放置和可排序组合

jquery可排序/可拖动双重事件触发