【问题标题】:How do I drag multiple elements at once with JavaScript or jQuery?如何使用 JavaScript 或 jQuery 一次拖动多个元素?
【发布时间】:2011-08-06 09:16:12
【问题描述】:

我希望能够使用 jQuery 拖动一组元素,就像我在 Windows 桌面上选择并拖动多个图标一样。

我找到了threedubmedia的jQuery.event.drag的demo:

http://threedubmedia.com/code/event/drag/demo/multi
http://threedubmedia.com/code/event/drag#demos

我觉得这个插件很棒。这是一个好的和受欢迎的图书馆吗?你知道使用它的网站或应用程序吗?

是否有任何其他库或插件可以拖动多个对象?

jQuery UI可以拖动多个对象吗?

【问题讨论】:

  • 拖动多个对象是什么意思?您可以将 jQuery UI 的可拖动元素绑定到多个元素,但要使所有/部分元素同时移动,您必须在其之上实现您的逻辑。
  • 是的,我想让所有/一些对象同时移动。
  • 我如何使用 jQuery UI 来做到这一点?
  • 查看文档,在事件中会有开始事件。尝试将 .ui-draggable-dragging 类添加到您要移动的其他元素。我可能错了,但我认为 UI 使用这个类来移动元素,所以它们会一起移动。
  • 请参阅stackoverflow.com/questions/793559/…,了解您正在寻找的解决方案。

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


【解决方案1】:
var selectedObjs;
var draggableOptions = {
    start: function(event, ui) {
        //get all selected...
        selectedObjs = $('div.selected').filter('[id!='+$(this).attr('id')+']');
    },
    drag: function(event, ui) {
        var currentLoc = $(this).position();
        var orig = ui.originalPosition;

        var offsetLeft = currentLoc.left-orig.left;
        var offsetTop = currentLoc.top-orig.top;

        moveSelected(offsetLeft, offsetTop);
    }       
};

$(document).ready(function() {
    $('#dragOne, #dragTwo').draggable(draggableOptions);
});

function moveSelected(ol, ot){
    console.log(selectedObjs.length);
    selectedObjs.each(function(){
        $this =$(this);
        var pos = $this.position();

        var l = $this.context.clientLeft;
        var t = $this.context.clientTop;

        $this.css('left', l+ol);
        $this.css('top', t+ot);
    })
}

【讨论】:

  • 感谢您向我展示如何使用 jQuery UI 进行多重拖动。这也有效。
  • 这个小提琴是建立在你的解决方案的基础上的,有一些小的更新:jsfiddle.net/zVZFq/358
  • @green 你知道当你从 A 移动一个组然后你从 B 移动(例如)时,div 会改变它们的位置吗?
  • @GelinLuo 如果与helper:'clone' 选项一起使用,示例小提琴不起作用,有什么想法吗?
【解决方案2】:

我是threedubmedia 插件的作者。我添加了这个功能来支持多个元素,因为我在其他任何地方都找不到令人满意的解决方案。

如果您需要一个适用于 jQuery UI 的解决方案,这里有一个插件,它添加了一些多拖功能,尽管演示在 Firefox for Mac 中似乎无法正常工作。

http://www.myphpetc.com/2009/11/jquery-ui-multiple-draggable-plugin.html

【讨论】:

  • 感谢您介绍您的插件。我可以通过单击(而不是通过 ctrl 单击)对项目进行分组吗?我可以自定义项目分组时的效果吗?您的演示在分组时会更改项目的颜色。但是我想在分组时将对象的位置移动一些像素。我可以用你的插件处理拖尾事件吗?
  • 对不起,如果我不完全清楚。我是threedubmedia插件的作者。我只是发布另一个链接作为使用 jQuery UI 创建类似功能的示例。
  • 对不起,我的误解。从threedubmedia插件的作者那里得到答案,我感到非常高兴和惊讶!我将您的 jquery.event.drag 用于我现在正在开发的软件。我喜欢你的插件。正如你所说,它非常简单而强大。
【解决方案3】:

这对我有用。

Fiddle here:

var selectedObjs;
var draggableOptions = {
start: function(event, ui) {
    //get all selected...
    if (ui.helper.hasClass('selected')) selectedObjs = $('div.selected');
    else {
        selectedObjs = $(ui.helper);
        $('div.selected').removeClass('selected')
    }
},
drag: function(event, ui) {
    var currentLoc = $(this).position();
    var prevLoc = $(this).data('prevLoc');
    if (!prevLoc) {
        prevLoc = ui.originalPosition;
    }

    var offsetLeft = currentLoc.left-prevLoc.left;
    var offsetTop = currentLoc.top-prevLoc.top;

    moveSelected(offsetLeft, offsetTop);
    selectedObjs.each(function () {
           $(this).removeData('prevLoc');
        });
    $(this).data('prevLoc', currentLoc);
}
};

$('.drag').draggable(draggableOptions).click(function()     {$(this).toggleClass('selected')});


function moveSelected(ol, ot){
console.log("moving to: " + ol + ":" + ot);
selectedObjs.each(function(){
    $this =$(this);
    var p = $this.position();
    var l = p.left;
    var t = p.top;
    console.log({id: $this.attr('id'), l: l, t: t});


    $this.css('left', l+ol);
    $this.css('top', t+ot);
})
}

感谢 ChrisThompson 和 green 提供了几乎完美的解决方案。

【讨论】:

    【解决方案4】:

    我想补充一下(这在 google 中排名很高),因为这个线程中的插件都没有工作,而且 jquery ui 不支持原生,这是一个简单优雅的解决方案。

    将可拖动元素包装在一个容器中并使用一个事件一次将它们全部拖动,这允许单个可拖动元素和多元素可拖动元素(但不是真正的选择性可拖动元素)。

    jQuery(document).click(function(e) {
    
      if(e.shiftKey) {
          jQuery('#parent-container').draggable();
      }
    }); 
    

    【讨论】:

    • 这个解决方案是显而易见的,但并不总是可行的,尤其是当您想要一次拖动的元素位于不同的容器中并且此顺序无法更改时。
    【解决方案5】:

    看看这个:

    https://github.com/someshwara/MultiDraggable

    用法:$(".className").multiDraggable({ group: $(".className")});

    将一组元素拖到一起。组也可以是指定单个元素的数组。

    点赞:$("#drag1").multiDraggable({ group: [$("#drag1"),$("#drag2") ]});

    【讨论】:

    • 这是否适用于在调用 multiDraggable 后动态创建的元素?
    • 是的。这个插件适用于动态创建的元素 - jQuery live 用于实现这一点。
    • jQuery .live() 从 1.9 版开始被移除。
    【解决方案6】:

    将您的项目放入某个容器中,并使该容器可拖动。您需要将handle 选项设置为您的项目元素的类。此外,您还需要在拖动后重新计算项目位置。显然,当您取消选择项目时,您必须从该容器中取出它们并放回它们的原点。

    【讨论】:

    • 这样您将无法选择该容器中的单个元素。
    • 这是一个很好的解决方案,但需要在放入容器时进行一些计算,并在使用 CTRL 释放后销毁父容器并添加元素 +1
    【解决方案7】:

    这是我使用的,在我的情况下工作。

    function selectable(){
    $('#selectable').selectable({
      stop: function() {
        $('.ui-selectee', this).each(function(){
            if ($('.ui-selectee').parent().is( 'div' ) ) {
                $('.ui-selectee li').unwrap('<div />');
            }
    
    
        });
    
        $('.ui-selected').wrapAll('<div class=\"draggable\" />');
    
        $('.draggable').draggable({ revert : true });   
      }
    });
    

    };

    【讨论】:

      【解决方案8】:

      jquery UI 中有Draggable

      您所要做的就是:

      $(selector).draggable(); // and you are done!
      

      在此处查看示例:http://jsfiddle.net/maniator/zVZFq/


      如果你真的想要多重拖动,你可以尝试使用一些点击事件来将块固定在适当的位置

      $('.drag').draggable();
      
      $('.drag').click(function(){
          console.log(this, 'clicked')
          var data = $(this).data('clicked');
          var all = $('.all');
          if(data == undefined || data == false){
              $(this).data('clicked', true);
              this.style.background = 'red';
              $(this).draggable('disable');
              if(all.children().length <= 0){
                  all.draggable().css({
                      top: '0px',
                      left: '0px',
                      width: $(window).width(),
                      height: $(window).height(),
                      'z-index': 1
                  });
              }
              var top = parseInt(all.css('top').replace('px','')) +
                          parseInt($(this).css('top').replace('px',''))
              var left = parseInt(all.css('left').replace('px','')) +
                          parseInt($(this).css('left').replace('px',''))
              $(this).css({
                  top: top,
                  left: left
              })
              $('.all').append($(this));
          }
          else {
              $(this).data('clicked', false);
              this.style.background = 'grey';
              $(this).draggable('enable');
              $('body').append($(this));
              if(all.children() <= 0){
                  all.draggable('destroy');
              }
              /*
              var top = parseInt(all.css('top').replace('px','')) -
                          parseInt($(this).css('top').replace('px',''))
              var left = parseInt(all.css('left').replace('px','')) -
                          parseInt($(this).css('left').replace('px',''))
              $(this).css({
                  top: top,
                  left: left
              })*/
          }
      })
      

      在此处查看示例:http://jsfiddle.net/maniator/zVZFq/5

      【讨论】:

      • 感谢您的回答。但我认为 draggable() 使单对象拖动成为可能,而不是多对象拖动。 threedubmedia.com/code/event/drag/demo/multi 是多对象拖动的演示。 1. 首先,单击一些对象。 2. 然后物体的颜色发生了变化。 3.如果你拖动之前点击的对象,所有点击的对象都会移动。
      • @js_ 你可以使用多个选择器,它们都将变成可拖动的。我做个小提琴,一分钟
      • @js_ 我做了一个小提琴并将其附加到我的答案中。
      • @_js 我在这里更新了小提琴:jsfiddle.net/maniator/zVZFq/5 它并不完美,但我相信你可以修复它^_^
      • @WesleyMurch 我已经更新了 Neals 的小提琴,它可以在没有 multidraggable 插件的情况下完美运行:jsfiddle.net/zVZFq/358
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多