Вот пример, основанный на моем комментарии.
$(function() {
$(".draggable").draggable({
containment: "parent"
});
$("#snaptarget").droppable({
accept: ".draggable",
drop: function(e, ui) {
var cPPos = ui.position;
var cOPos = ui.offset;
var cPosOff = {
top: Math.round(cOPos.top) % 90,
left: Math.round(cOPos.left) % 83
};
var sPos = {
top: Math.round(cOPos.top),
left: Math.round(cOPos.left)
};
console.log("Dropped", cPPos, cOPos, cPosOff, sPos);
var $item = ui.draggable;
if (cPosOff.top > 0 && cPosOff.top < 70) {
sPos.top = sPos.top - cPosOff.top;
console.log("DROP - TOP: " + cOPos.top + " lower to " + sPos.top);
} else {
sPos.top = sPos.top + (90 - cPosOff.top);
console.log("DROP - TOP: " + cOPos.top + " rise to " + sPos.top);
}
if (cPosOff.left > 0 && cPosOff.left < 61) {
sPos.left = sPos.left - cPosOff.left;
console.log("DROP - LEFT: " + cOPos.left + " left to " + sPos.left);
} else {
sPos.left = sPos.left + (83 - cPosOff.left);
console.log("DROP - LEFT: " + cOPos.left + " right to " + sPos.left);
}
$item.appendTo($(this)).css({
margin: 0,
position: "absolute",
top: sPos.top + "px",
left: sPos.left + "px"
});
}
});
});
.drag-area {
min-height: 300px;
}
.draggable {
width: 80px;
height: 80px;
display: inline-block;
margin: 0 10px 10px 0;
font-size: .9em;
}
.ui-widget-header p,
.ui-widget-content p {
margin: 0;
}
#snaptarget {
height: 173px;
position: relative;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<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 class="drag-area">
<div id="snaptarget" class="ui-widget-header">
</div>
<br style="clear:both">
<div id="draggable" class="draggable ui-widget-content">
<p>A</p>
</div>
<div id="draggable2" class="draggable ui-widget-content">
<p>B</p>
</div>
<div id="draggable3" class="draggable ui-widget-content">
<p>C</p>
</div>
<div id="draggable4" class="draggable ui-widget-content">
<p>D</p>
</div>
<div id="draggable5" class="draggable ui-widget-content">
<p>E</p>
</div>
</div>
Я оставил вещи немного неубранными, чтобы вы получили немного больше отзывов в консоли.При перетаскивании требуется более полный диапазон движения, но когда пользователь отбрасывает элемент, вы хотите, чтобы он защелкнулся в позиции.
Изначально я собирался получить допуск 50% и обнаружил, что это слишкомжадный, поэтому я стрелял примерно на 75% терпимости.Например, если пользователь отбрасывает элемент, и у него есть top,left
из {12, 140}
, вы можете захотеть, чтобы он привязался к {0,83}
.Если пользователь ленивый или не знает, что он щелкнет, он может перетащить его близко, чтобы нанести удар по следующей цели, мой код будет иметь допуск ~ 25% для следующего блока справа.Поэтому, если они упадут до {12,164}
, он сдвинется к правому блоку, который ближе {0,166}
.
Надеюсь, что поможет.