我有以下内容:
我正在尝试将其设置为当您拖动项目时,它只会被删除到您可以看到的div元素,并且不被掩盖
所以我用了这个js:
$(".draggable").draggable({
helper: "clone"
})
$("#bottom, .draggable").droppable({
drop: function(event, ui) {
var $this = $(this),
$dragged = $(ui.draggable);
$this.append($dragged.clone());
},
hoverClass: "dragHover"
})
但它会将元素放在两个位置,即使只有一个放置区域不可见!
如何修复它以便不发生?
小提琴:http://jsfiddle.net/maniator/Wp4LU/
额外信息重新创建页面没有小提琴:
HTML:
<div id="top">
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
<div class="draggable">
Lorem ipsum dolor sit amet
</div>
</div>
<div id="bottom"></div>
CSS:
.draggable {
border: 1px solid green;
background: white;
padding: 5px;
}
.dragHover{
background: blue;
}
#top {
height: 500px;
overflow-y: scroll;
}
#bottom {
height: 150px;
overflow-y: scroll;
border: red solid 4px;
}
答案 0 :(得分:2)
如果我找对你 - 这个应该解决你的问题 - http://jsfiddle.net/Wp4LU/60/ 您也可以编写自定义接受函数 - http://jqueryui.com/demos/droppable/#option-accept
代码:
var draggableList = $('#top');
$(".draggable").draggable({
helper: "clone"
});
$("#bottom, .draggable").droppable({
drop: function(event, ui) {
var $this = $(this),
$dragged = $(ui.draggable);
if ($this.hasClass("draggable")) {
if ($this.position().top >= draggableList.height() ||
$this.position().top + $this.outerHeight() >=
draggableList.height())
return;
}
$this.append($dragged.clone());
},
hoverClass: "dragHover"
});
答案 1 :(得分:2)
尝试使用accept
功能进行设置。
的 The working demo. 强>
$("#bottom, .draggable").droppable({
drop: function(event, ui) {
var $this = $(this),
$dragged = $(ui.draggable);
$this.append($dragged.clone());
},
accept: function () {
var $this = $(this), divTop= $("#top");
if ($this.is(".draggable")) {
return $this.offset().top < divTop.offset().top + divTop.height() ;
}
return true;
},
hoverClass: "dragHover"
});
答案 2 :(得分:1)
根据来源(jquery.ui.droppable.js),drop操作将搜索每个符合条件的dropable,并将drop函数应用于与其相交的每一个:
drop: function(draggable, event) {
var dropped = false;
$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
if(!this.options) return;
if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
dropped = this._drop.call(this, event) || dropped;
(旧版本的最后一个“OR”条件被反转,所以它只适用于一个droppable。使用jQuery 1.5.2 / jQuery UI 1.8.9尝试你的小提琴,并看到它只下降到一个元素,虽然是“错误的”......)
目前在$.ui.intersect
函数中实现的每个容差模式只考虑(x,y)坐标:
switch (toleranceMode) {
case 'fit':
return (l <= x1 && x2 <= r
&& t <= y1 && y2 <= b);
break;
case 'intersect':
return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
&& x2 - (draggable.helperProportions.width / 2) < r // Left Half
&& t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
&& y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
break;
...
因此,除非有人添加了z-index感知容忍模式,否则您唯一的选择是以某种方式解决问题。我建议先将每个可放置的候选者添加到一个集合中,当它下降时,只选择与屏幕“最接近”的那个:
$("#bottom, .draggable").droppable({
over: function(event, ui) {
if ( !ui.draggable.data("drop-candidates") )
ui.draggable.data("drop-candidates",[]);
ui.draggable.data("drop-candidates").push(this);
},
out: function(event, ui) {
var that = this,
candidates = ui.draggable.data("drop-candidates") || [];
ui.draggable.data("drop-candidates", $.grep(candidates, function(e) {
return e != that;
});
},
drop: function(event, ui) {
var $this = $(this),
$dragged = $(ui.draggable);
var candidates = $.data("drop-candidates").sort(closestToScreen);
if ( candidates[0] == this )
$this.append($dragged.clone());
},
hoverClass: "dragHover"
})
现在,实施closestToScreen
比较器是棘手的部分。 W3C CSS Specification描述了渲染引擎应该如何对要绘制的元素进行排序,但到目前为止我还无法找到访问此信息的简单方法。我也asked this question在这里,也许有人会找到一个好方法。
P.S。如果修改jQuery UI源是一个选项,您可以尝试使用document.getElementFromPoint
实现z-index感知容差模式,如this answer所述建议的问题:
var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
switch (toleranceMode) {
...
case 'z-index-aware':
return document.elementFromPoint(x1,y1) == droppable;
break;
(这将确保仅可拖动的左上角正下方的元素将被视为“足够好”作为放置目标 - 不理想,但比目前为止更好;类似的解决方案可以改为使用鼠标指针坐标)
而且,不,您不能将此方法与之前提供的解决方法一起使用:在发生丢弃的那一刻,拖动助手是最接近屏幕的元素...(编辑: d'oh!如果实施为公差模式也不行,原因相同......)
答案 3 :(得分:0)
如果您只想放置元素,可以看到您可以更改选择器:
$(".draggable:visible").draggable({
helper: "clone"
});
$("#bottom, .draggable:visible").droppable({
drop: function(event, ui) {
var $this = $(this),
$dragged = $(ui.draggable);
$this.append($dragged.clone());
},
hoverClass: "dragHover"
});
或者当你隐藏一个元素时,用其他东西改变它的'draggable class。