如何根据条件恢复可拖动的jquery UI的位置

Posted

技术标签:

【中文标题】如何根据条件恢复可拖动的jquery UI的位置【英文标题】:how to revert position of a jquery UI draggable based on condition 【发布时间】:2011-03-06 12:48:01 【问题描述】:

我有一个可拖动的元素和一个可放置的元素。将拖动的项目放在 dropzone 上后,我将尝试执行以下 jquery 伪代码:

if(draggedelement == value)

$(draggedelement).hide();


else

$(draggedelement).revert();


revert() 函数将拖动的项目移回其原始位置。

如何做到这一点?

附:我知道可拖动的“还原”选项,但是只有在拖动的项目没有进入放置区时才会激活。

【问题讨论】:

【参考方案1】:

为此有一些内置选项,在您的.draggable() 上,将revert option 设置为'invalid',如果它没有成功放置到可放置对象上,它会返回,如下所示:

$("#draggable").draggable( revert: 'invalid' );

然后在您的.droppable() 中使用accept option 设置对掉落有效的内容,例如:

$("#droppable").droppable( accept: '#draggable' );​

当你放手时,任何不匹配这个选择器的东西都会被重置,you can see a full demo here。如果您需要过滤选择器无法提供的功能,accept 选项也有一个功能,如下所示:

$("#droppable").droppable( 
  accept: function(dropElem) 
    //dropElem was the dropped element, return true or false to accept/refuse it
  
);​

【讨论】:

@Nick Craver,我可以请您在这里查看一个与 jQuery 可拖放相关的问题:***.com/questions/54498364/… 吗?【参考方案2】:

我有一个用例,我必须在 droppable 的 drop 方法中运行一些逻辑来确定可拖动对象是否应该恢复。我使用以下方法来实现这一点:

$('.draggable-elements').draggable(
  revert: function() 
    if ($(this).hasClass('drag-revert')) 
      $(this).removeClass('drag-revert');
      return true;
    
  
);

$('.droppable-elements').droppable(
  drop: function(event, ui) 
    if ( % conditional logic check here % ) 
      return $(ui.draggable).addClass('drag-revert');
    
  
);

我的用例是一个表格,其中每个单元格都是一个代表 5 分钟时间段的可放置单元。我的可拖动对象是从一个单元格开始的预订,但连续运行多个单元格以表示预订时间。

我不希望任何可拖动对象重叠,因为这将代表双重预订。因此,在放置之后,我发现行中的所有可拖动对象,不包括我刚刚移动的对象,并检查是否有任何重叠。如果有重叠,我的条件逻辑返回 true 并恢复可拖动对象。

下一阶段是触发 ajax 调用来更新数据库,如果服务器端逻辑显示移动无效,我希望返回错误状态并恢复可拖动对象。

附:这是我的第一个答案,如果我做错了什么,请见谅。我们很乐意接受有关如何提供良好答案的提示。

编辑:在尝试了我的 AJAX 调用之后,我意识到 droppable.drop 函数有机会在 draggable.revert 函数运行之前执行它。当我的 AJAX 调用返回 false 时,窗口已经过去,并且添加类太晚了,draggable.revert 无法做出反应。

因此,我不再依赖 draggable.revert 函数,而是仅对 AJAX 响应进行操作,如果为 false,则使用 animate() 将可拖动对象返回到其原始位置,如下所示:

$( '.draggable-elements' ).draggable();

$( '.droppable-elements' ).droppable(
  drop: function( event, ui ) 
    var postData = 
      id: 1,
      ...
    ;
    $.post( '/ajax/url', postData, function( response ) 
      var response = $.parseJSON( response );
      if ( response.status != 1 ) 
        return ui.draggable.animate( left: 0, top: 0, 500 );
      
    
  
);

您可能需要 draggable.start/drag 将可拖动对象的原始 left 和 top 值添加为数据属性,但对我来说,上述工作正常。

【讨论】:

我认为最优雅的解决方案。使用 droppable accept 太过分了,因为它会随着可拖动对象的每次移动而被评估。相反,drggable revert 仅在可拖动对象被实际放下时评估一次。 很好的答案。工作正常【参考方案3】:

尝试将该代码添加到“drop”事件中。这是demo。

html

<div class="draggable ui-widget-content correct"><p>1</p></div>
<div class="draggable ui-widget-content"><p>2</p></div>
<div class="draggable ui-widget-content"><p>3</p></div>
<div class="draggable ui-widget-content"><p>4</p></div>
<br style="clear: both">
<div id="droppable" class="ui-widget-header">
  <p>Drop me here</p>
</div>

脚本

$(function() 

 $(".draggable").draggable( revert: true );

 $("#droppable").droppable(
  activeClass: 'ui-state-hover',
  hoverClass: 'ui-state-active',
  // uncomment the line below to only accept the .correct class..
  // Note: the "drop" function will not be called if not ".correct"
  //  accept : '.correct',
  drop: function(event, ui) 
   // alternative method:
   // if (ui.draggable.find('p').text() == "1") 
   if (ui.draggable.is('.correct')) 
    $(this).addClass('ui-state-highlight').find('p').html('You got it!');
    // cloning and appending prevents the revert animation from still occurring
    ui.draggable.clone(true).css('position', 'inherit').appendTo($(this));
    ui.draggable.remove();
    else 
    $('#droppable > p').html('Not that one!')
    setTimeout(function() $('#droppable > p').html('Drop here'); , 1000);
   
  
 );

);

正如您在脚本中看到的,您可以查找 .correct 类或里面的文本(注释掉的行)

【讨论】:

【参考方案4】:
$("#droppable").droppable( 
    accept: function(dropElem) 
        //dropElem was the dropped element, return true or false to accept/refuse it
        if($(this).data('stoneclass') == dropElem.attr("id"))
            return true;
    

);​

这用于从一组可拖动对象中仅接受一个可拖动对象;到一个正确的droppable,在一组droppables中。

P.S 抱歉,如果语言无法理解 =)

【讨论】:

【参考方案5】:

我发现如果我简单地设置 top:0 和 left:0,则该项目不再是可拖动的。为了“强制”恢复,我必须这样做:

$draggedObj.css( top: 0, left: 0 )
$draggedObj.draggable( "destroy" )
$draggedObj.draggable(...whatever my draggable options are...);

【讨论】:

以上是关于如何根据条件恢复可拖动的jquery UI的位置的主要内容,如果未能解决你的问题,请参考以下文章

如何在恢复可拖动的 jQuery UI 时删除动画?

滚动浏览器时使用错误起始位置的可拖动 jQuery UI 元素?

使用网格恢复“无效”不会使用 jQuery UI Draggable 返回到起始位置

Jquery UI Droppable revert不能再次删除

Jquery ui“恢复”模态表单上的位置取消

在 jQuery 中,如何在 ajax 调用失败时恢复可拖动对象?