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

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

if(draggedelement == value){

$(draggedelement).hide();

}
else{

$(draggedelement).revert();

}

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

如何做到这一点?

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

【问题讨论】:

    标签: jquery jquery-ui-draggable jquery-ui-droppable


    【解决方案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
      }
    });​
    

    【讨论】:

    【解决方案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...});
        

        【讨论】:

          猜你喜欢
          • 2011-02-09
          • 1970-01-01
          • 1970-01-01
          • 2012-10-08
          • 2011-10-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-28
          相关资源
          最近更新 更多