【问题标题】:Is there a JQuery plugin which combines Draggable and Selectable有没有结合 Draggable 和 Selectable 的 JQuery 插件
【发布时间】:2010-10-16 20:33:03
【问题描述】:

我希望实现一个包含许多项目的 Web 界面,这些项目可以选择并拖动以定位它们,可以分组或单独。真的很像 Windows 桌面。

我们已经在使用 JQuery,所以添加它是首选。 JQuery UI Draggables 和 Selectables 单独完成了我们想要的大部分工作,但并没有真正协同工作以提供我们正在寻找的那种效果。

JQ 插件网站让我完全不知所措(它的“流行”算法似乎不是很有用),并欢迎提供有关避免大量车轮改造的最佳方法的指导,因为我猜想这个比喻已经完成了。

【问题讨论】:

标签: jquery html draggable


【解决方案1】:

我也需要做同样的事情,我不想使用 eyecon.ro 的界面扩展。经过一番研究,我找到了Combining Selectables And Draggables Using jQuery UI。讲得很好,但是要使代码 sn-ps 运行,您必须深入研究它。我能够让它工作。我稍微改变了它,这是我完成它的方法。它需要修改才能在生产级别使用,但我希望它有所帮助。

// this creates the selected variable
// we are going to store the selected objects in here
var selected = $([]), offset = {top:0, left:0}; 

// initiate the selectable id to be recognized by UI
$("#selectable").selectable({
    filter: 'div',
});

// declare draggable UI and what we are going to be doing on start
$("#selectable div").draggable({
     start: function(ev, ui) {
        selected = $(".ui-selected").each(function() {
           var el = $(this);
            el.data("offset", el.offset());
        });

        if( !$(this).hasClass("ui-selected")) $(this).addClass("ui-selected");
        offset = $(this).offset();
    },
    drag: function(ev, ui) {
        var dt = ui.position.top - offset.top, dl = ui.position.left - offset.left;

        // take all the elements that are selected expect $("this"), which is the element being dragged and loop through each.
        selected.not(this).each(function() {
             // create the variable for we don't need to keep calling $("this")
             // el = current element we are on
             // off = what position was this element at when it was selected, before drag
             var el = $(this), off = el.data("offset");
             el.css({top: off.top + dt, left: off.left + dl});
        });
    }
});

CSS 样式能够看到正在发生的事情:

#selectable {   width: 100%; height: 100%;}
#selectable div {
    background: #ffc;
    line-height: 25px;
    height: 25px;
    width: 200px;
    border: 1px solid #fcc;
    }
#selectable div.ui-selected {
    background: #fcaf3e;
    }
#selectable div.ui-selecting {
    background: #8ae234;
    }

HTML 标记:

<div id="selectable">
    <div>item 1</div>
    <div>item 2</div>
    <div>item 3</div>
    <div>item 4</div>
</div>

【讨论】:

  • 这段代码的主要问题是它不能让你控制点击添加额外的项目。
  • 这似乎只允许您拖动多个选定的项目,我无法通过单击选择任何可选项目(更不用说 ctrl 单击)
  • 此代码会导致在拖动时随机丢失可调整大小。这是张贴在stackoverflow.com/questions/34698117/… 如何解决?
【解决方案2】:

这个问题是相关的,但已经过时了;答案也是如此。 @idFlood 的 jsfiddle 的 Here's an updated version,适用于 jQuery 1.9.1 + jQueryUI 1.10.3:

// store selected elements and the offset of the dragged element
var selected = $([]), offset = {top:0, left:0}; 

$( "#selectable > div" ).draggable({
    start: function (event, ui) {
        var $this = $(this);

        if ($this.hasClass("ui-selected")) {
            // if this is selected, attach current offset
            // of each selected element to that element
            selected = $(".ui-selected").each(function() {
                var el = $(this);
                el.data("offset", el.offset());
            });
        } else {
            // if this is not selected, clear current selection
            selected = $([]);
            $( "#selectable > div" ).removeClass("ui-selected");
        }
        offset = $this.offset();
    },

    drag: function (event, ui) {
        // drag all selected elements simultaneously
        var dt = ui.position.top - offset.top, dl = ui.position.left - offset.left;
        selected.not(this).each(function() {
            var $this = $(this);
            var elOffset = $this.data("offset");
            $this.css({top: elOffset.top + dt, left: elOffset.left + dl});
        });
    }
});

// enable marquee selecting and deselect on outside click...
$( "#selectable" ).selectable();

// ...but manually implement selection to prevent interference from draggable()
$( "#selectable" ).on("click", "div", function (e) {
    if (!e.metaKey && !e.shiftKey) {
        // deselect other elements if meta/shift not held down
        // $( "#dc-modules .dc-module" ).removeClass("ui-selected");
        $( "#selectable > div" ).removeClass("ui-selected");
        $(this).addClass("ui-selected");
    } else {
        if ($(this).hasClass("ui-selected")) {
            $(this).removeClass("ui-selected");
        } else {
            $(this).addClass("ui-selected");
        }
    }
});

我遇到了 _mouseStop() 调用引发错误的问题,因此我将其删除;这意味着ui-selecting 状态不再在单击时发生,但所有其他功能保持不变。

【讨论】:

  • 这个解决方案效果很好,但我无法让它与 droppable 一起工作。您认为该解决方案是否有任何内在的东西会与 droppable 冲突,或者我应该继续对这段代码进行抨击?
  • @ericsoco 此代码导致拖动时可调整大小的随机 loff。这是张贴在stackoverflow.com/questions/34698117/… 如何修复?
【解决方案3】:

我对 Sinan Yasar 给出的答案做了一些修改。它并不完美,但它的行为已经更像我的行为了。

一个主要的附加功能是调用选择的点击监听器。

// manually trigger the "select" of clicked elements
$( "#selectable > div" ).click( function(e){
    if (e.metaKey == false) {
        // if command key is pressed don't deselect existing elements
        $( "#selectable > div" ).removeClass("ui-selected");
        $(this).addClass("ui-selecting");
    }
    else {
        if ($(this).hasClass("ui-selected")) {
            // remove selected class from element if already selected
            $(this).removeClass("ui-selected");
        }
        else {
            // add selecting class if not
            $(this).addClass("ui-selecting");
        }
    }

    $( "#selectable" ).data("selectable")._mouseStop(null);
});

您可以在此处查看完整的工作示例:http://jsfiddle.net/DXrNn/4/

还有一个 jquery-ui 插件可以做到这一点:http://code.google.com/p/jqdragdropmultiselect/ 问题是它看起来没有维护。

编辑:如果您定义了可拖动的“过滤器”选项,则需要在 selectable._mouseStop(null) 之前调用 selectable.refresh()。

$( "#selectable > div" ).click( function(e){
  ...
  var selectable = $("#container").data("selectable");
  selectable.refresh();
  selectable._mouseStop(null);
  ...

【讨论】:

  • 无论我如何在 jsfiddle 中尝试您的解决方案,我都无法拖动任何元素,只能选择。铬 19。
  • @trusktr 试试jQuery 1.8.3jQueryUI 1.9.2
  • @trusktr 因为这个stackoverflow.com/questions/14366322/… 似乎你需要 jQueryUI 1.10 才能使用 jQuery EDGE
  • 知道如何让可拖动助手工作吗?我不想直接通过css()移动选定的兄弟姐妹
  • @pferdefleisch 此代码会导致在拖动过程中随机丢失可调整大小,如stackoverflow.com/questions/34698117/… 中所发布。如何解决?
【解决方案4】:

还有另一种方式,可能是我用过的更简洁的方式。子元素是被选择者,父元素将具有“ui-selectable”类。

$("#parentContainer").selectable({
  selected: function(event, ui) {
    let selected = ui.unselected.id;
   document.getElementById(selected).style.border = '1px solid blue'
  }
  unselected: function(event, ui) {
    let unselected = ui.unselected.id;
    document.getElementById(unselected).style.border = ''
    $('#'+unselected).draggable('destroy')
  }
})

document.getElementbyId('childElement').addEventListener('mousedown', function() {
  $(this).draggable({
    cursor: crosshair
  })
})

【讨论】:

    猜你喜欢
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    • 2012-03-23
    • 2011-03-26
    • 1970-01-01
    • 2010-12-18
    • 2012-08-16
    • 1970-01-01
    相关资源
    最近更新 更多