gpt4 book ai didi

javascript - jQuery droppable - 在拖动期间接收事件(不仅仅是在初始拖动时)

转载 作者:行者123 更新时间:2023-12-03 21:39:05 25 4
gpt4 key购买 nike

我正在使用jQuery droppable (与 jQuery draggable 结合使用)允许用户通过将列表中的项目拖放到表格上来将行添加到 HTML 表格中。

这很有效,但目前的逻辑是,当用户在表格行上拖放时,新行将添加到他们拖放的行的下方。

如果新行的添加位置基于用户是放在现有行的上半部分还是下半部分,那就更好了。

这很容易在 drop 中计算。事件,但我需要在用户拖动时提供 UI 反馈(例如,我将通过两个 CSS 类 droppable-abovedroppable-below 来实现)。

这似乎不可能,因为 over事件仅触发一次;当用户最初拖动可放置元素时。

是否可以获取 over当用户位于可放置元素上方时,每次鼠标移动都会触发事件?

如果是这样,那么我就可以这样做:

$("tr.droppable").droppable({
over: function(event, ui) {
if (/* mouse is in top half of row */) {
$(this).addClass("droppable-above").removeClass("droppable-below");
}
else {
$(this).removeClass("droppable-above").addClass("droppable-below");
}
},

out: function(event, ui) {
$(this).removeClass("droppable-above").removeClass("droppable-below");
},

drop: function(event, ui) {
$(this).removeClass("droppable-above").removeClass("droppable-below");
if (/* mouse is in top half of row */) {
// Add new row above the dropped row
}
else {
// Add new row below the dropped row
}
}
});

CSS 样式类似于...

droppable-above { border-top: solid 3px Blue; }
droppable-below { border-bottom: solid 3px Blue; }

最佳答案

正如您所说,over(就像其对应的out)仅在可放置对象上引发一次。另一方面,每次鼠标移动时,draggabledrag 事件都会引发,并且似乎适合该任务。然而,这种策略有两个问题:

  • drag 会被引发,无论可拖动对象是否实际上位于可放置对象之上,
  • 即使在这种情况下,droppable 也不会传递给事件处理程序。

解决这两个问题的一种方法是使用 jQuery 的 data()over 处理程序中关联可放置和可拖动。设施,并在 outdrop 处理程序中取消它们的关联:

$("tr.droppable").droppable({
over: function(event, ui) {
if (/* mouse is in top half of row */) {
$(this).removeClass("droppable-below")
.addClass("droppable-above");
}
else {
$(this).removeClass("droppable-above")
.addClass("droppable-below");
}
ui.draggable.data("current-droppable", $(this)); // Associate.
},

out: function(event, ui) {
ui.draggable.removeData("current-droppable"); // Break association.
$(this).removeClass("droppable-above droppable-below");
},

drop: function(event, ui) {
ui.draggable.removeData("current-droppable"); // Break association.
$(this).removeClass("droppable-above droppable-below");
if (/* mouse is in top half of row */) {
// Add new row above the dropped row.
}
else {
// Add new row below the dropped row.
}
}
});

现在,可拖动对象知道它所在的可放置对象,我们可以在 drag 事件处理程序中更新元素的外观:

$(".draggable").draggable({
drag: function(event, ui) {
var $droppable = $(this).data("current-droppable");
if ($droppable) {
if (/* mouse is in top half of row */) {
$droppable.removeClass("droppable-below")
.addClass("droppable-above");
} else {
$droppable.removeClass("droppable-above")
.addClass("droppable-below");
}
}
}
});

下面的代码是一个简单的测试用例,演示了该解决方案(它基本上填补了上面注释的空白,并将常见模式重构为辅助函数)。可删除的设置比前面的示例稍微复杂一些,主要是因为新创建的表行必须像其 sibling 一样可删除。

您可以在 this fiddle 中看到结果.

HTML:

<div class="draggable">New item 1</div>
<div class="draggable">New item 2</div>
<div class="draggable">New item 3</div>
<div class="draggable">New item 4</div>
<div class="draggable">New item 5</div>
<p>Drag the items above into the table below.</p>
<table>
<tr class="droppable"><td>Item 1</td></tr>
<tr class="droppable"><td>Item 2</td></tr>
<tr class="droppable"><td>Item 3</td></tr>
<tr class="droppable"><td>Item 4</td></tr>
<tr class="droppable"><td>Item 5</td></tr>
</table>

CSS:

p {
line-height: 32px;
}

table {
width: 100%;
}

.draggable {
background-color: #d0ffff;
border: 1px solid black;
cursor: pointer;
padding: 6px;
}

.droppable {
background-color: #ffffd0;
border: 1px solid black;
}

.droppable td {
padding: 10px;
}

.droppable-above {
border-top: 3px solid blue;
}

.droppable-below {
border-bottom: 3px solid blue;
}

Javascript:

$(document).ready(function() {
$(".draggable").draggable({
helper: "clone",
drag: function(event, ui) {
var $droppable = $(this).data("current-droppable");
if ($droppable) {
updateHighlight(ui, $droppable);
}
}
});

initDroppable($(".droppable"));

function initDroppable($elements)
{
$elements.droppable({
over: function(event, ui) {
var $this = $(this);
updateHighlight(ui, $this);
ui.draggable.data("current-droppable", $this);
},
out: function(event, ui) {
cleanupHighlight(ui, $(this));
},
drop: function(event, ui) {
var $this = $(this);
cleanupHighlight(ui, $this);
var $new = $this.clone().children("td:first")
.html(ui.draggable.html()).end();
if (isInUpperHalf(ui, $this)) {
$new.insertBefore(this);
} else {
$new.insertAfter(this);
}
initDroppable($new);
}
});
}

function isInUpperHalf(ui, $droppable)
{
var $draggable = ui.draggable || ui.helper;
return (ui.offset.top + $draggable.outerHeight() / 2
<= $droppable.offset().top + $droppable.outerHeight() / 2);
}

function updateHighlight(ui, $droppable)
{
if (isInUpperHalf(ui, $droppable)) {
$droppable.removeClass("droppable-below")
.addClass("droppable-above");
} else {
$droppable.removeClass("droppable-above")
.addClass("droppable-below");
}
}

function cleanupHighlight(ui, $droppable)
{
ui.draggable.removeData("current-droppable");
$droppable.removeClass("droppable-above droppable-below");
}
});

关于javascript - jQuery droppable - 在拖动期间接收事件(不仅仅是在初始拖动时),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6199890/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com