我想要一个可排序的列表,但我也希望该列表中的元素可放置到我定义为可放置的 div 中。我似乎找不到办法做到这一点。有任何想法吗?
6 回答
这是 Colin 解决方案的简化版本。
最大的不同是这个方案没有存储可排序元素的整个html,而只存储当前拖动的item。如果项目被放置在可放置区域上,则它会被插入到它的原始位置。
无论如何,这是代码:
<!doctype html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/jquery-ui.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var dropped = false;
var draggable_sibling;
$("#sortable").sortable({
start: function(event, ui) {
draggable_sibling = $(ui.item).prev();
},
stop: function(event, ui) {
if (dropped) {
if (draggable_sibling.length == 0)
$('#sortable').prepend(ui.item);
draggable_sibling.after(ui.item);
dropped = false;
}
}
});
$(".droppable").droppable({
activeClass: 'active',
hoverClass:'hovered',
drop:function(event,ui){
dropped = true;
$(event.target).addClass('dropped');
}
});
});
</script>
<style type="text/css">
#sortable li{
clear:both;
float:left;
}
.droppable {
clear:both;
height:300px;
width:400px;
background-color:#CCC;
}
.droppable.active { background: #CFC; }
.droppable.hovered { background: #CCF; }
.dropped { background: #f52; }
</style>
</head>
<body>
<ul id="sortable">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
<li id="six">Six</li>
</ul>
<div class="droppable">Drop Here</div>
<div class="droppable">Drop Here</div>
</body>
</html>
如果一个项目被拖到列表中的一个新位置,然后放在<ul>
和 droppable之外,它仍然会遇到与 Colin 解决方案相同的问题<div>
。然后该项目将不会重置,但会占据列表中的最后一个位置(在 Google Chrome 中测试)。无论如何,这很容易通过一些鼠标悬停检测来解决,或者它甚至可能是理想的行为。
据我所知,我之前发布的代码的问题是,在可排序对象的 mouseup 之前调用了可放置对象的放置函数,并且由于我重写了列表,可排序对象变得很生气(因为缺乏更好的术语)。这有点猜测。
查看最终代码:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.js"></script>
<script type="text/javascript">
var dropped = false;
var templateHtml;
$(document).ready(function(){
setSortable();
$("#droppable").droppable({
activeClass: 'active',
hoverClass:'hovered',
accept:".drop",
drop:function(event,ui){
dropped = true;
//alert(ui.draggable.text());
}
});
});
function setSortable(){
$("#sortable").sortable({
stop:function(event,ui){
if(dropped){
$("#sortable").sortable('destroy').html(templateHtml);
dropped = false;
setSortable();
}
}
});
$("#sortable li").addClass("drop").bind('mousedown',function(){
templateHtml = $("#sortable").html();
});
}
</script>
<style type="text/css">
#sortable li{
clear:both;
float:left;
}
#droppable {
clear:both;
height:300px;
width:400px;
background-color:#CCC;
}
#droppable.active {
background-color:#CFC;
}
#droppable.hovered {
background-color:#CCF;
}
</style>
</head>
<body>
<ul id="sortable">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
<li id="six">Six</li>
</ul>
<div id="droppable">
Drop Here
</div>
</body>
这里涉及大量怪癖。
我试图在可排序的开始事件中保存#sortable html,但是在应用了所有 ui-css 后调用了该 get,并最终将列表元素放置在疯狂的地方。所以,我需要在 LI 上使用 mousedown 功能。
setSortable 在一个函数中,因为停止事件重写了可排序的,我猜这是“递归的”。不确定这里的确切术语,但我们可以使用令人讨厌的混淆。
幸运的是,droppable 的 drop 函数在 sortables 停止函数之前被调用,所以我能够设置一个全局“dropped”变量,用于查看元素是否被删除。
我仍然很惊讶这并不容易做到,我认为 jQuery 将具有更好地处理它的功能。也许我错过了什么?
不完全是您要求的,但我需要一个初始容器,可以将项目拖到另一个可排序的容器中 - 我认为我应该分享它。这就是我实现它的方式(jQuery 1.8.3):
$("#sortable-list").sortable();
$("#initial-list div").draggable({
revert: true,
revertDuration: 0
});
$("#initial-list").droppable({
accept: ".item-selected",
drop: function(e, ui) {
var dropped = ui.draggable;
var droppedOn = $(this);
var itemInOtherList = $(this).children("#" + dropped.attr('id'));
itemInOtherList.removeClass('ui-state-disabled').draggable({ disabled: false });
dropped.remove();
}
});
$("#sortable-list").droppable({
accept: ".item-initial",
drop: function(e, ui) {
var dropped = ui.draggable;
var droppedOn = $(this);
droppedOn.append(dropped.clone()
.removeAttr('style')
.removeClass("item-initial")
.addClass("item-selected"));
dropped.animate(dropped.data().origPosition, {
complete: function() {
$(this).addClass('ui-state-disabled').draggable({ disabled: true });
}
});
}
});
JSFiddle:http: //jsfiddle.net/Muskar/dwz4mvxa/8/
我花了一整天的时间在这上面,我已经接近了很多,但仍然没有像我想要的那样做得好。我现在有了我需要的功能,但是抛出了一个 Javascript 错误。
如果元素被丢弃在可放置对象中,而不是列表中,问题是让可排序列表返回到其先前的位置。目前,我正在保存 html onmousedown,然后在 droppable 的 drop 函数中重写 html。这可行,但它给我一个 jquery 变量是空错误。谁能找到更好的解决方案?
代码:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.js"></script>
<script type="text/javascript">
var templateHtml;
$(document).ready(function(){
$("#sortable").sortable();
$("#sortable li").addClass("drop").bind('mousedown',function(){
templateHtml = $("#sortable").html();
});
$("#droppable").droppable({
activeClass: 'active',
hoverClass:'hovered',
accept:".drop",
drop:function(event,ui){
$("#sortable").sortable('destroy').html(templateHtml);
$("#sortable").sortable();
$("#sortable li").addClass("drop").bind('mousedown',function(){
templateHtml = $("#sortable").html();
});
}
});
});
</script>
<style type="text/css">
#sortable li{
clear:both;
float:left;
}
#droppable {
clear:both;
height:300px;
width:400px;
background-color:#CCC;
}
#droppable.active {
background-color:#CFC;
}
#droppable.hovered {
background-color:#CCF;
}
</style>
</head>
<body>
<ul id="sortable">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
<li id="six">Six</li>
</ul>
<div id="droppable">
Drop Here
</div>
</body>
通过使每个目标 DIV 成为自己的可排序对象,能够获得类似的最终结果。
然后,我通过 connectWith 使所有可排序的对象都能够连接和共享可拖动对象。
就像是:
var connects = '#main_sortable, div.target';
$('#main_sortable').sortable({ connectWith: connect });
$('div').sortable({ connectWith: connect} );
如果您可以允许其他可放置区域也可以排序,则可以将connectWith 选项与通用选择器一起使用:
<div id="droppable1" class="droppable-area"></div>
<div id="droppable2" class="droppable-area"></div>
<div id="droppable3" class="droppable-area"></div>
您的 jQuery 代码将是:
$('.droppable-area').sortable({ connectWith: '.droppable-area' });
无论如何,这个解决方案对我来说效果很好。