【问题标题】:How to swap element with jQuery UI draggable and droppable?如何使用可拖放的 jQuery UI 交换元素?
【发布时间】:2009-08-30 06:32:21
【问题描述】:

我有两个 div.containers。两个容器都有 div.item。使用 jQuery,如何通过拖放交换 div.item 元素?两个元素都应该能够再次重新交换。

有什么简单的方法吗?

谢谢...

【问题讨论】:

    标签: jquery jquery-ui drag-and-drop


    【解决方案1】:

    @Ei Maung..

    我从你肮脏的解决方案中得到了顺利的解决方案..

    $(document).ready(function () {
        src = null;
        options = {
            revert:true,
            /*axis: 'x',*/
            opacity: 0.8,
            start: function() {
                    src = $(this).parent();
            }
        };
    
        $(".item").draggable(options);
        $(".container").droppable({
            drop: function(event, ui) {
                    src.append(
                            $('.item', this).remove().clone()
                            .removeClass().addClass("item")
                            .css({"left": '', "opacity": '',"top":''})
                            .draggable(options)
                    );
    
                    $(this).append(
                            ui.draggable.remove().clone()
                            .removeClass().addClass("item")
                            .css({"left": '', "opacity": '',"top":''})
                            .draggable(options)
                    );
            }
        });
    
    });
    

    【讨论】:

    • 这可行,但不幸的是它允许重复条目。如果将此与 src[0] 进行比较(如果它不为空),则可以防止问题发生。
    【解决方案2】:

    可能有点晚了,但我认为这是一个更好的解决方案...将发布用于文档/搜索目的,以防其他人发现这有用

    注意:您还需要在您的 UI 构建中加载 jQuery UI 的 Position 元素才能使此解决方案正常工作。

    在我的示例中,我正在创建一组可拖动的“优惠券”,它们可以放置在不同的位置。在给定时间,只有一张优惠券可以放在任何可投放区域。

    为了管理分配给可放置区域的优惠券,我创建了一些辅助对象,我将使用它们来扩展可拖动和可放置原型的选项对象:

    var dropObj = { hasCoupon: false, couponId: null }
    var couponObj = { dropId: null }
    

    然后(在 DOM 就绪时)扩展:

    $.extend( $.ui.droppable.prototype.options, dropObj );
    $.extend( $.ui.draggable.prototype.options, couponObj );
    

    最后,设置您的可拖动对象和可放置对象...当您设置可放置对象时,请使用 jquery UI 的位置助手来协助交换可拖动对象...

    $('.selector').droppable({
        drop: function( event, ui ) {   
            var current, swapId;
            if ( $(this).droppable('option', 'hasCoupon') === false ) {
                // ...
            } else {
                current = $(this).droppable('option', 'couponId');
                swapId = ui.draggable.draggable('option', 'dropId');
                if ( swapId !== null ){
                    current.position({ 
                        my: "center", at: "center", of: swapId,
                        using: function(to) {
                            $(this).animate({
                                top: to.top,
                                left: to.left
                            }, ui.draggable.revertDuration, function() {
                                swapId.droppable('option', 'hasCoupon', true);
                                swapId.droppable('option', 'couponId', current);
                                current.draggable('option', 'dropId', swapId);
                            });
                        }
                    });
                }
            }
            $(this).droppable('option', 'hasCoupon', true);
            $(this).droppable('option', 'couponId', ui.draggable);
            ui.draggable.draggable('option', 'dropId', $(this));
            ui.draggable.position({ my: "center", at: "center", of: $(this),
                using: function(to) { $(this).animate({ top: to.top, left: to.left }, 150 ); }
            });
        }
    });
    

    注意:我们在动画回调中为交换手动设置 couponId/dropId 的值,因为在这种情况下实际上不会触发拖动事件(移动是通过 jquery 动画调用来处理的)。

    我最初尝试在 dragstart/dragstop 上使用 .trigger(),但它们并没有像我认为的那样触发 drop 事件。

    【讨论】:

      【解决方案3】:

      也许我遗漏了一些东西,但我认为我有一个更简单的解决方案:

      $('.droppable').droppable({
          drop: function (event, ui) {
              ui.draggable.parent().append($(this).children());
      
              $(this).append(ui.draggable);
      
              ui.draggable.css({
                  left: '',
                  top: ''
              });
          }
      });
      

      简而言之:

      1. 当可拖动项被拖放到可放置区域时,获取可拖动项的(上一个)父元素。
      2. 从可拖放区域中移除子元素并将它们附加到可拖动项的父元素。
      3. 从其(前一个)父元素中移除可拖动项目,并将其附加到放置它的可放置区域。
      4. 此时可拖动项目的位置会有些奇怪,因为我们已从页面中删除元素并重新附加它们,因此请重置其位置。

      【讨论】:

        【解决方案4】:
            $(function () {
                $('#sortable').sortable({
                    start: function (e, ui) {
                        // creates a temporary attribute on the element with the old index
                        $(this).attr('data-previndex', ui.item.index());
                    },
                    update: function (e, ui) {
                        // gets the new and old index then removes the temporary attribute
                        newIndex = ui.item.index();
                        oldIndex = $(this).attr('data-previndex');
                        $(this).removeAttr('data-previndex');
                        tempNew = newIndex - 1;
                        tempoldIndex = oldIndex;
                        if (oldIndex > newIndex) {
                            tempNew = newIndex + 1;
                            $("#sortable li:eq(" + tempNew + ")").insertAfter($("#sortable li:eq(" + tempoldIndex + ")"));
                        } else {
                            $("#sortable li:eq(" + tempNew + ")").insertBefore($("#sortable li:eq(" + tempoldIndex + ")"));
                        }
                    }
                });
            });
        

        // ubaidullah chan 编码并验证

        【讨论】:

          【解决方案5】:

          好的,我得到了肮脏的解决方案......

          $(document).ready(function () {
              src = null;
              options = {
                  revert:true,
                  axis: 'x',
                  opacity: 0.8,
                  start: function() {
                      src = $(this).parent();
                  }
              };
          
              $(".item").draggable(options);
              $(".container").droppable({
                  drop: function(event, ui) {
                      src.append(
                          $('.item', this).remove().clone()
                          .removeClass().addClass("item")
                          .css({"left": '', "opacity": ''})
                          .draggable(options)
                      );
          
                      $(this).append(
                          ui.draggable.remove().clone()
                          .removeClass().addClass("item")
                          .css({"left": '', "opacity": ''})
                          .draggable(options)
                      );
                  }
              });
          });
          

          希望有人可以改进这个... :)

          欢呼……

          【讨论】:

            【解决方案6】:

            我在 pengoworks 找到了这个解决方案:

            jQuery.fn.swap = function(b) {
                b = jQuery(b)[0];
                var a = this[0];
                var t = a.parentNode.insertBefore(document.createTextNode(''), a);
                b.parentNode.insertBefore(a, b);
                t.parentNode.insertBefore(b, t);
                t.parentNode.removeChild(t);
                return this;
            };
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2010-11-12
              • 1970-01-01
              • 2012-11-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-09-19
              相关资源
              最近更新 更多