将 "nephew" draggable 拖动到 "aunt" droppable,同时保持 CSS 和尺寸
Drag a "nephew" draggable to an "aunt" droppable while maintaining CSS and dimensions
我想将某个父项中的可拖动 #red
、 嵌套 拖动到某个可放置的 #green
,它位于 div结构。
div
的尺寸需要用 percent
表示(响应),顶层 div
必须是 position: relative;
,这可能让事情变得更复杂。
为了比较,这一切都适用于更简单的情况,其中 draggable #blue
和 droppable #green
是兄弟元素,但在 "nephew" 场景中中断(#red
#green
).
我明白我需要:
helper: clone
外甥(#red
)div,还有要appendTo: "body",
让我外甥素可以 "escape"
- 我还知道我需要将一些样式(尤其是
position: relative;
)附加到 .ui-draggable-dragging
,以便在传输过程中参考父元素计算侄子元素的尺寸。
到目前为止一切顺利。
还有一个皱纹:侄子被拖的时候,它会往旁边跳,永远掉不下来。
这是怎么回事?
$(function() {
$("#blue").draggable({
snap: ".hexagon",
snapMode: "inner",
snapTolerance: 20,
opacity: 0.7,
addClasses: true,
// stack: ".item",
revert: "invalid"
});
$("#red").draggable({
snap: ".hexagon",
snapMode: "inner",
snapTolerance: 20,
opacity: 0.7,
addClasses: true,
// stack: ".item",
revert: "invalid",
appendTo: "body",
helper: "clone",
});
$("#green").droppable({
accept: ".hexagon",
tolerance: "fit",
drop: function(event, ui) {
$(this)
.addClass("ui-state-highlight")
.find("span")
.html("Dropped!");
}
});
});
.hexagon {
width: 20%;
padding-top: 25%;
overflow: hidden;
-webkit-clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
-webkit-shape-outside: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
float: left;
position: relative;
z-index: 1;
}
.outer {
position: relative;
z-index: 0;
}
.inner {
background-color: red;
z-index: 9999;
position: absolute;
margin: 0 auto;
width: 100%;
top: 0;
bottom: 0;
}
.textstyle {
color: white;
font-family: sans-serif;
top: 25%;
left: 10%;
right: 10%;
bottom: 10%;
text-align: center;
position: absolute;
font-size: 1vw;
}
.green {
background-color: green;
z-index: 1000;
}
.blue {
background-color: blue;
}
.red {
background-color: red;
}
.ui-draggable-dragging {
position: relative;
padding-top: 25%;
width: 20%;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="green" class="hexagon outer green">
<span class="textstyle">
I am the dropzone.
</span>
</div>
<div id="blue" class="hexagon outer blue">
<span class="textstyle">
I drag just fine, because I'm just a sibling element.
</span>
</div>
<div class="hexagon outer">
<div id="red" class="hexagon inner red">
<span class="textstyle">
I am nested, and I make a mess when dragged.
I am the nephew.
</span>
</div>
</div>
为什么分身会跳?
似乎 jQuery 可拖动插件正在通过强制 .ui-draggable-dragging
到 position: relative;
该插件实际上是将克隆相对于元素最初在页面上的位置定位在左侧。
要修复此行为,请向克隆添加覆盖以绝对定位它:
.red.ui-draggable-dragging {
position: absolute;
bottom: auto;
}
此外,添加 bottom: auto;
以覆盖 .inner
设置的 bottom
值,因为这会导致克隆拉伸。
为什么不能删除克隆?
这是因为 tolerance: "fit"
根据文档:
"fit"
: Draggable overlaps the droppable entirely.
可放置小部件 - (https://api.jqueryui.com/droppable/#option-tolerance)
这仍然会导致问题,因为克隆是绝对定位的,因为它的 width
未计算为与原始 .hexagon
相同(原始的 width: 20%;
是根据body
宽度,而克隆的 width: 20%;
是根据视口计算的)。为了缓解这种情况,body
上的默认浏览器 margin
已被抑制(尽管这也可以通过将 .hexagon
包装在容器中来解决)。
如果拖动动作不需要很精确tolerance: "fit"
可以改成tolerance: "intersect"
这样可以留出更多余地
$(function() {
$("#blue").draggable({
snap: ".hexagon",
snapMode: "inner",
snapTolerance: 20,
opacity: 0.7,
addClasses: true,
// stack: ".item",
revert: "invalid"
});
$("#red").draggable({
snap: ".hexagon",
snapMode: "inner",
snapTolerance: 20,
opacity: 0.7,
addClasses: true,
// stack: ".item",
revert: "invalid",
appendTo: "body",
helper: "clone"
});
$("#green").droppable({
accept: ".hexagon",
tolerance: "fit",
drop: function(event, ui) {
$(this)
.addClass("ui-state-highlight")
.find("span")
.html("Dropped!");
}
});
});
body {
margin: 0;
}
.hexagon {
width: 20%;
padding-top: 25%;
overflow: hidden;
-webkit-clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
-webkit-shape-outside: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
float: left;
position: relative;
z-index: 1;
}
.outer {
position: relative;
z-index: 0;
}
.inner {
background-color: red;
z-index: 9999;
position: absolute;
margin: 0 auto;
width: 100%;
top: 0;
bottom: 0;
}
.textstyle {
color: white;
font-family: sans-serif;
top: 25%;
left: 10%;
right: 10%;
bottom: 10%;
text-align: center;
position: absolute;
font-size: 1vw;
}
.green {
background-color: green;
z-index: 1000;
}
.blue {
background-color: blue;
}
.red {
background-color: red;
}
.ui-draggable-dragging {
position: relative;
padding-top: 25%;
width: 20%;
}
.red.ui-draggable-dragging {
position: absolute;
bottom: auto;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="green" class="hexagon outer green">
<span class="textstyle">
I am the dropzone.
</span>
</div>
<div id="blue" class="hexagon outer blue">
<span class="textstyle">
I drag just fine, because I'm just a sibling element.
</span>
</div>
<div class="hexagon outer">
<div id="red" class="hexagon inner red">
<span class="textstyle">
I am nested, and I make a mess when dragged.
I am the nephew.
</span>
</div>
</div>
我想将某个父项中的可拖动 #red
、 嵌套 拖动到某个可放置的 #green
,它位于 div结构。
div
的尺寸需要用 percent
表示(响应),顶层 div
必须是 position: relative;
,这可能让事情变得更复杂。
为了比较,这一切都适用于更简单的情况,其中 draggable #blue
和 droppable #green
是兄弟元素,但在 "nephew" 场景中中断(#red
#green
).
我明白我需要:
helper: clone
外甥(#red
)div,还有要appendTo: "body",
让我外甥素可以 "escape"- 我还知道我需要将一些样式(尤其是
position: relative;
)附加到.ui-draggable-dragging
,以便在传输过程中参考父元素计算侄子元素的尺寸。
到目前为止一切顺利。
还有一个皱纹:侄子被拖的时候,它会往旁边跳,永远掉不下来。
这是怎么回事?
$(function() {
$("#blue").draggable({
snap: ".hexagon",
snapMode: "inner",
snapTolerance: 20,
opacity: 0.7,
addClasses: true,
// stack: ".item",
revert: "invalid"
});
$("#red").draggable({
snap: ".hexagon",
snapMode: "inner",
snapTolerance: 20,
opacity: 0.7,
addClasses: true,
// stack: ".item",
revert: "invalid",
appendTo: "body",
helper: "clone",
});
$("#green").droppable({
accept: ".hexagon",
tolerance: "fit",
drop: function(event, ui) {
$(this)
.addClass("ui-state-highlight")
.find("span")
.html("Dropped!");
}
});
});
.hexagon {
width: 20%;
padding-top: 25%;
overflow: hidden;
-webkit-clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
-webkit-shape-outside: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
float: left;
position: relative;
z-index: 1;
}
.outer {
position: relative;
z-index: 0;
}
.inner {
background-color: red;
z-index: 9999;
position: absolute;
margin: 0 auto;
width: 100%;
top: 0;
bottom: 0;
}
.textstyle {
color: white;
font-family: sans-serif;
top: 25%;
left: 10%;
right: 10%;
bottom: 10%;
text-align: center;
position: absolute;
font-size: 1vw;
}
.green {
background-color: green;
z-index: 1000;
}
.blue {
background-color: blue;
}
.red {
background-color: red;
}
.ui-draggable-dragging {
position: relative;
padding-top: 25%;
width: 20%;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="green" class="hexagon outer green">
<span class="textstyle">
I am the dropzone.
</span>
</div>
<div id="blue" class="hexagon outer blue">
<span class="textstyle">
I drag just fine, because I'm just a sibling element.
</span>
</div>
<div class="hexagon outer">
<div id="red" class="hexagon inner red">
<span class="textstyle">
I am nested, and I make a mess when dragged.
I am the nephew.
</span>
</div>
</div>
为什么分身会跳?
似乎 jQuery 可拖动插件正在通过强制 .ui-draggable-dragging
到 position: relative;
该插件实际上是将克隆相对于元素最初在页面上的位置定位在左侧。
要修复此行为,请向克隆添加覆盖以绝对定位它:
.red.ui-draggable-dragging {
position: absolute;
bottom: auto;
}
此外,添加 bottom: auto;
以覆盖 .inner
设置的 bottom
值,因为这会导致克隆拉伸。
为什么不能删除克隆?
这是因为 tolerance: "fit"
根据文档:
"fit"
: Draggable overlaps the droppable entirely.
可放置小部件 - (https://api.jqueryui.com/droppable/#option-tolerance)
这仍然会导致问题,因为克隆是绝对定位的,因为它的 width
未计算为与原始 .hexagon
相同(原始的 width: 20%;
是根据body
宽度,而克隆的 width: 20%;
是根据视口计算的)。为了缓解这种情况,body
上的默认浏览器 margin
已被抑制(尽管这也可以通过将 .hexagon
包装在容器中来解决)。
如果拖动动作不需要很精确tolerance: "fit"
可以改成tolerance: "intersect"
这样可以留出更多余地
$(function() {
$("#blue").draggable({
snap: ".hexagon",
snapMode: "inner",
snapTolerance: 20,
opacity: 0.7,
addClasses: true,
// stack: ".item",
revert: "invalid"
});
$("#red").draggable({
snap: ".hexagon",
snapMode: "inner",
snapTolerance: 20,
opacity: 0.7,
addClasses: true,
// stack: ".item",
revert: "invalid",
appendTo: "body",
helper: "clone"
});
$("#green").droppable({
accept: ".hexagon",
tolerance: "fit",
drop: function(event, ui) {
$(this)
.addClass("ui-state-highlight")
.find("span")
.html("Dropped!");
}
});
});
body {
margin: 0;
}
.hexagon {
width: 20%;
padding-top: 25%;
overflow: hidden;
-webkit-clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
-webkit-shape-outside: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
float: left;
position: relative;
z-index: 1;
}
.outer {
position: relative;
z-index: 0;
}
.inner {
background-color: red;
z-index: 9999;
position: absolute;
margin: 0 auto;
width: 100%;
top: 0;
bottom: 0;
}
.textstyle {
color: white;
font-family: sans-serif;
top: 25%;
left: 10%;
right: 10%;
bottom: 10%;
text-align: center;
position: absolute;
font-size: 1vw;
}
.green {
background-color: green;
z-index: 1000;
}
.blue {
background-color: blue;
}
.red {
background-color: red;
}
.ui-draggable-dragging {
position: relative;
padding-top: 25%;
width: 20%;
}
.red.ui-draggable-dragging {
position: absolute;
bottom: auto;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="green" class="hexagon outer green">
<span class="textstyle">
I am the dropzone.
</span>
</div>
<div id="blue" class="hexagon outer blue">
<span class="textstyle">
I drag just fine, because I'm just a sibling element.
</span>
</div>
<div class="hexagon outer">
<div id="red" class="hexagon inner red">
<span class="textstyle">
I am nested, and I make a mess when dragged.
I am the nephew.
</span>
</div>
</div>