我正在寻求实现一个网页界面,其中包含许多项目,可以选择并拖动它们来定位它们,分组或单独。就像Windows桌面一样。
我们已经在使用JQuery,因此添加它将是首选。 JQuery UI Draggables和Selectables分别完成了我们想要的大部分工作,但并没有真正协同工作以提供我们正在寻找的那种效果。
我对JQ插件网站完全不知所措(它的'流行'算法看起来似乎不太有用),并欢迎指导,以避免在这里避免大量轮盘改造的最佳方法,正如我猜的那样这个比喻已经完成了。
答案 0 :(得分:20)
我还需要做同样的事情,我不想使用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样式能够看到发生了什么:
#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>
答案 1 :(得分:10)
这个问题是相关的,但已经过时了;答案也是如此。 @ 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
状态,但所有其他功能都保持不变。
答案 2 :(得分:4)
我对Sinan Yasar给出的答案做了一些修改。它并不完美,但它已经表现得更像我除外了。
一个主要的补充是一个调用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);
});
您可以在此处查看完整的工作示例:http://jsfiddle.net/DXrNn/4/
还有一个可用的jquery-ui插件:http://code.google.com/p/jqdragdropmultiselect/ 问题在于它看起来没有维护。
编辑:如果你定义了draggable的“filter”选项,你需要在selectable._mouseStop(null)之前调用selectable.refresh()。
$( "#selectable > div" ).click( function(e){
...
var selectable = $("#container").data("selectable");
selectable.refresh();
selectable._mouseStop(null);
...
答案 3 :(得分:0)
还有另一种方式,可能是我用过的更简洁的方式。子元素是被选择者,父元素将具有“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
})
})