如何获得 .droppable() 的自定义容差效果?
How to get custom tolerance effect for .droppable()?
我有一个可拖动的 #box
div,我可以将其拖放到多个可拖放的 .ru
div 之一上。 #box
的高度大约是 .ru
div 高度的 3 倍,但是,所以我正在使用 .droppable
的 tolerance
选项,但似乎没有什么适合我想要的。
我希望 #box
根据 #box
的前三分之一悬停在其中一个 droppables 上的时间悬停在其中一个 droppables 上。
我尝试使用 tolerance: pointer
并设置 .draggable()
选项 cursorAt: {top: 15}
,但这会使 #box
在启动拖动时跳转到新位置,但我没有这样做'想要。
我现在正在尝试从 #box
的顶部添加一个 child div, #test
15px,我想知道是否有办法当 #test
超过 .ru
时悬停在 .ru
上激活?或者,是否有一种好方法可以让悬停激活,正如我所描述的那样,不使用 child div?
FIDDLE: https://jsfiddle.net/joL53wkq/4/
HTML:
<div id="containment">
<div id="box">
<div id="test">
</div>
</div>
</div>
CSS:
#box {
background-color: teal;
width: 500px;
height: 92px;
position: absolute;
z-index: 50;
}
#test{
position: relative;
top: 15px;
width: 100%;
height: 1px;
background-color: blue;
}
#containment {
background-color: #ddd;
width: 500px;
height: 800px;
}
.ru {
background-color: red;
width: 500px;
height: 30px;
margin-top: 1px;
}
.hover {
background-color: yellow;
}
JS:
for(i=1; i<20; i++){
$("#containment").append("<div class='ru'>")
}
$( "#box" ).draggable({
revert: "invalid",
});
$( ".ru" ).droppable({
hoverClass: "hover",
tolerance:"intersect",
drop: function(event, ui) {
ui.draggable.position({
of: $(this),
my: 'left top',
at: 'left top'
});
}
});
管理公差的函数称为intersect,您可以重新定义它并添加自定义公差选项。像这样的东西似乎可行,它可能需要一些调整和测试,但它应该给你一些想法:
$.ui.intersect = function(draggable, droppable, toleranceMode) {
if (!droppable.offset) {
return false;
}
var draggableLeft, draggableTop,
x1 = (draggable.positionAbs || draggable.position.absolute).left,
y1 = (draggable.positionAbs || draggable.position.absolute).top,
x2 = x1 + draggable.helperProportions.width,
y2 = y1 + draggable.helperProportions.height,
l = droppable.offset.left,
t = droppable.offset.top,
r = l + droppable.proportions.width,
b = t + droppable.proportions.height;
switch (toleranceMode) {
case "custom":
//you can define your rules here
return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
x2 - (draggable.helperProportions.width / 2) < r && // Left Half
t < y1 && // Bottom Half
b > y1 + 15 ); // Top Half
case "fit":
return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
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
case "pointer":
draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width );
case "touch":
return (
(y1 >= t && y1 <= b) || // Top edge touching
(y2 >= t && y2 <= b) || // Bottom edge touching
(y1 < t && y2 > b) // Surrounded vertically
) && (
(x1 >= l && x1 <= r) || // Left edge touching
(x2 >= l && x2 <= r) || // Right edge touching
(x1 < l && x2 > r) // Surrounded horizontally
);
default:
return false;
}
};
for(i=1; i<20; i++){
$("#containment").append("<div class='ru'>")
}
$( "#box" ).draggable({
revert: "invalid",
});
$( ".ru" ).droppable({
hoverClass: "hover",
tolerance:"custom",
drop: function(event, ui) {
ui.draggable.position({
of: $(this),
my: 'left top',
at: 'left top'
});
}
});
我有一个可拖动的 #box
div,我可以将其拖放到多个可拖放的 .ru
div 之一上。 #box
的高度大约是 .ru
div 高度的 3 倍,但是,所以我正在使用 .droppable
的 tolerance
选项,但似乎没有什么适合我想要的。
我希望 #box
根据 #box
的前三分之一悬停在其中一个 droppables 上的时间悬停在其中一个 droppables 上。
我尝试使用 tolerance: pointer
并设置 .draggable()
选项 cursorAt: {top: 15}
,但这会使 #box
在启动拖动时跳转到新位置,但我没有这样做'想要。
我现在正在尝试从 #box
的顶部添加一个 child div, #test
15px,我想知道是否有办法当 #test
超过 .ru
时悬停在 .ru
上激活?或者,是否有一种好方法可以让悬停激活,正如我所描述的那样,不使用 child div?
FIDDLE: https://jsfiddle.net/joL53wkq/4/
HTML:
<div id="containment">
<div id="box">
<div id="test">
</div>
</div>
</div>
CSS:
#box {
background-color: teal;
width: 500px;
height: 92px;
position: absolute;
z-index: 50;
}
#test{
position: relative;
top: 15px;
width: 100%;
height: 1px;
background-color: blue;
}
#containment {
background-color: #ddd;
width: 500px;
height: 800px;
}
.ru {
background-color: red;
width: 500px;
height: 30px;
margin-top: 1px;
}
.hover {
background-color: yellow;
}
JS:
for(i=1; i<20; i++){
$("#containment").append("<div class='ru'>")
}
$( "#box" ).draggable({
revert: "invalid",
});
$( ".ru" ).droppable({
hoverClass: "hover",
tolerance:"intersect",
drop: function(event, ui) {
ui.draggable.position({
of: $(this),
my: 'left top',
at: 'left top'
});
}
});
管理公差的函数称为intersect,您可以重新定义它并添加自定义公差选项。像这样的东西似乎可行,它可能需要一些调整和测试,但它应该给你一些想法:
$.ui.intersect = function(draggable, droppable, toleranceMode) {
if (!droppable.offset) {
return false;
}
var draggableLeft, draggableTop,
x1 = (draggable.positionAbs || draggable.position.absolute).left,
y1 = (draggable.positionAbs || draggable.position.absolute).top,
x2 = x1 + draggable.helperProportions.width,
y2 = y1 + draggable.helperProportions.height,
l = droppable.offset.left,
t = droppable.offset.top,
r = l + droppable.proportions.width,
b = t + droppable.proportions.height;
switch (toleranceMode) {
case "custom":
//you can define your rules here
return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
x2 - (draggable.helperProportions.width / 2) < r && // Left Half
t < y1 && // Bottom Half
b > y1 + 15 ); // Top Half
case "fit":
return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
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
case "pointer":
draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width );
case "touch":
return (
(y1 >= t && y1 <= b) || // Top edge touching
(y2 >= t && y2 <= b) || // Bottom edge touching
(y1 < t && y2 > b) // Surrounded vertically
) && (
(x1 >= l && x1 <= r) || // Left edge touching
(x2 >= l && x2 <= r) || // Right edge touching
(x1 < l && x2 > r) // Surrounded horizontally
);
default:
return false;
}
};
for(i=1; i<20; i++){
$("#containment").append("<div class='ru'>")
}
$( "#box" ).draggable({
revert: "invalid",
});
$( ".ru" ).droppable({
hoverClass: "hover",
tolerance:"custom",
drop: function(event, ui) {
ui.draggable.position({
of: $(this),
my: 'left top',
at: 'left top'
});
}
});