【问题标题】:jQuery UI - Droppable only accept one draggablejQuery UI - Droppable 只接受一个可拖动的
【发布时间】:2011-04-26 07:04:48
【问题描述】:

我正在制作一个应用程序,它使用一个可拖放的div 和几个可拖动的divs。如何使 droppable 不接受多个可拖动的div?我用 Google 搜索了,但没有找到任何解决方法。


我想到了一个解决方法。我如何检查这个可放置的 div 中是否有放置的元素?如果它很忙,则恢复这个试图被丢弃的可拖动对象

【问题讨论】:

    标签: jquery jquery-ui


    【解决方案1】:

    OK 找到了一个很好的解决方案,基本上在“drop”上,我将 droppable 设置为仅接受已拖入其中的项目。

    当您“禁用”时,您需要重新初始化的“out”事件不再可用,因此我只是切换了符合条件的项目。

    那么我可以使用 OUT 事件重新接受所有可拖动项,因为没有其他内容被接受,所以 OUT 不会被其他可拖动项触发:

    $(".drop-zone").droppable({
        drop: function(event, ui) { 
            $(this).droppable('option', 'accept', ui.draggable);
        },
        out: function(event, ui){
            $(this).droppable('option', 'accept', '.drag-item');
            }   
        });
    });
    

    【讨论】:

    • 我也遇到了同样的问题。智能解决方案!干得好!
    • 不幸的是,如果可拖动元素恢复为 .drop-zone,则会中断 - 例如用户将元素放在无效区域上。
    • @yayitswei U̶s̶i̶n̶g̶ ̶'̶o̶v̶e̶r̶:̶'̶i̶n̶s̶t̶e̶a̶d̶̶o̶f̶ ̶'̶o̶u̶t̶'̶̶s̶h̶o̶u̶l̶d̶̶f̶i̶x̶̶i̶t̶.̶ 我错了。
    【解决方案2】:

    您可以在第一个drop 之后销毁.droppable() 小部件,如下所示:

    $(".droppable").droppable({
        drop: function( event, ui ) {
            $(this).droppable("destroy");
        }
    });
    

    You can try out a demo here.

    【讨论】:

    • 好的,但是当我释放这个可放置字段时,如何让它再次可放置
    • @Emil - 如果您需要重新启用它,您可以稍后使用"disable" 然后使用"enable" 而不是"destroy" :)
    • 我做到了,但我不知道如何启用它。我试过了:enable_Droppable,但它没有用。我应该用什么代替'out'
    【解决方案3】:

    简单的皮西。只需在鼠标悬停时启用所有 .drop-zone,然后检查当前悬停的 .drop-zone 是否包含可拖动元素

    $('.drop-zone').droppable({
      over: function(event, ui) {
    
        // Enable all the .droppable elements
        $('.droppable').droppable('enable');
    
        // If the droppable element we're hovered over already contains a .draggable element, 
        // don't allow another one to be dropped on it
        if($(this).has('.draggable').length) {
            $(this).droppable('disable');
        }
      }
    });
    

    【讨论】:

    • 只想指出,这是这里为数不多的真正有效的回应之一。
    • $(this).has('.draggable').length 对我来说总是返回 0。可能有新的语法吗?
    【解决方案4】:

    我花了很多时间来解决这个问题,最后它对我有用:

    $( ".drop-zone" ).droppable({
        classes: {
            "ui-droppable-active": "ui-state-active",
            "ui-droppable-hover": "ui-state-hover"
        },
        accept: function( draggable ){
            if (!$(this).hasClass('dropped') || draggable.hasClass('dropped')){
                return true;
            }
            return false;
        },
        drop: function( event, ui ) {
            $(this).addClass('dropped');
            ui.draggable.addClass('dropped');
        },
        out: function( event, ui ){
            $(this).removeClass('dropped');
            ui.draggable.removeClass('dropped');
        }
    });
    

    【讨论】:

      【解决方案5】:

      此解决方案解决了 Likwid_T 回答中的一个主要错误。

      $('.draggable').draggable({
        start: function(ev, ui) {  
          $('.ui-droppable').each(function(i, el) {
            if (!$(el).find('.ui-draggable').length) $(el).droppable('enable');
          });
        }
      });
      
      $('.droppable').droppable({
        drop: function(ev, ui) {
          $(ev['target']).droppable('disable');
        }
      });
      

      【讨论】:

        【解决方案6】:

        这个怎么样:

        $(".drop-zone").droppable({
            accept: function(draggable) {
                return $(this).find("*").length == 0;
            });
        });
        

        这样accept函数只有在没有元素被删除时才返回true。

        【讨论】:

          【解决方案7】:

          要启用它,请使用选项:$(".selector").droppable({ disabled: **false** });

          【讨论】:

            【解决方案8】:

            你也可以反过来做,当 droppable 具有特定的类或属性时恢复可拖动对象(基于此示例:https://stackoverflow.com/a/3418306/1005334)。

            因此,例如,使用rel 属性(您也可以使用class 或其他东西),用于可放置:

            $('.drop-zone').droppable({
                drop: function () {
                    drop.attr('rel', 'filled');
                }
            });
            

            还有可拖动的:

            $('.draggable').draggable({
                revert: function (droppable) {
            
                    if (droppable.attr('rel') == 'filled') {
                        return true;
                    }
                }
            });
            

            【讨论】:

              【解决方案9】:

              我的解决方案类似于 Likwid_T 的,除了它使用 droppable drop 事件以及维护 draggables 和 droppables 之间的链接而不是 droppable 的 out 事件。我认为使用out 的问题在于,即使将可拖动对象拖到已经“完整”的可放置对象上,然后将其“移出”,它也会被触发。

              droppable({
                drop: function(event, ui) {
                  var $droppable = $(this);
                  var $draggable = ui.draggable;
              
                  // If the draggable is moved from another droppable, unlink it from the old droppable
                  var oldDropped = $draggable.data('dropped');
                  if(oldDropped) {
                    $draggable.data('dropped', null);
                    oldDropped.data('dragged', null);
                  }
              
                  // Link the draggable and droppable
                  $draggable.data('dropped', $droppable);
                  $droppable.data('dragged', $draggable);
                },
                accept: function() {
                  // Only accept if there is no draggable already associated
                  return !$(this).data('dragged');
                }
              });
              

              一个相关的功能是,将一个项目拖动到已经具有可拖动对象的 droppable 上,旧的项目将被替换并恢复到其初始位置。我就是这样做的:

              droppable({
                drop: function(event, ui) {
                  var $droppable = $(this);
                  var $draggable = ui.draggable;
              
                  // Reset position of any old draggable here
                  var oldDragged = $droppable.data('dragged');
                  if(oldDragged) {
                    // In the CSS I have transitions on top and left for .ui-draggable, so that it moves smoothly
                    oldDragged.css({top: 0, left: 0});
                    oldDragged.data('dropped', null);
                  }
              
                  // If the draggable is moved from another droppable, unlink it from the old droppable
                  var oldDropped = $draggable.data('dropped');
                  if(oldDropped) {
                    $draggable.data('dropped', null);
                    oldDropped.data('dragged', null);
                  }
              
                  // Link the draggable and droppable
                  $draggable.data('dropped', $droppable);
                  $droppable.data('dragged', $draggable);
                },
              });
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2021-09-14
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-02-27
                • 2013-06-22
                相关资源
                最近更新 更多