是否有结合 Draggable 和 Selectable 的 JQuery 插件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/705250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 09:36:25  来源:igfitidea点击:

Is there a JQuery plugin which combines Draggable and Selectable

jqueryhtmldraggable

提问by Will Dean

I'm looking to implement a web interface with a number of items which can be selected and dragged around to position them, either in groups or singly. Rather like the Windows Desktop, really.

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

We're using JQuery already, so additions to that would be first choice. JQuery UI Draggables and Selectables individually do much of what we want, but don't really work together to give the sort of effect we're looking for.

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

I am completely overwhelmed by the JQ plugin site (it's 'popular' algorithm doesn't seem very useful), and would welcome guidance as to the best way to avoid a lot of wheel-reinvention here, as I would guess that this metaphor has already been done.

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

采纳答案by Sinan

I also needed to do same thing, and i didn't want to use interface extension from eyecon.ro. After some research, I found Combining Selectables And Draggables Using jQuery UI. It is nicely told but to make the code snippets run you have to dig into it. I was able to make it work. I slightly changed it, this is my way to get it done. It needs modifications for using on production level, but i hope it helps.

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

// 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 Styles to be able to see what's happening:

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 Markup:

HTML 标记:

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

回答by ericsoco

This question is relevant, but is old; so are the answers. Here's an updated versionof @idFlood's jsfiddle, that works with jQuery 1.9.1 + jQueryUI 1.10.3:

这个问题是相关的,但已经过时了;答案也是如此。 这是@idFlood 的 jsfiddle的更新版本,适用于 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");
        }
    }
});

I had a problem with the _mouseStop() call throwing an error, so I removed it; this means that the ui-selectingstate no longer happens on click, but all other functionality remains intact.

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

回答by idFlood

I've made some modification to the answer given by Sinan Yasar. It's not perfect but it already behave much more like I would except.

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

One main addition is a click listener that calls the select.

一个主要的添加是调用选择的点击侦听器。

// 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);
});

You can see a complete working example here: http://jsfiddle.net/DXrNn/4/

你可以在这里看到一个完整的工作示例:http: //jsfiddle.net/DXrNn/4/

There is also a jquery-ui plugin available that does just that: http://code.google.com/p/jqdragdropmultiselect/The probleme is that it doesn't look maintained.

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

edit: if you define the "filter" option of the draggable, you will need to call selectable.refresh() before the selectable._mouseStop(null).

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

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