![](/img/trans.png)
[英]jQuery UI - Revert a jQuery draggable object back to its original?
[英]Revert a jQuery draggable object back to its original container on out event of droppable
我有一個可拖動的項目,如果不放在 droppable 中,它將恢復。 這很有效,直到用戶在 droppable 中放置一個項目。 如果他們認為他們在任何時候都犯了錯誤,那么他們將可拖動對象拉出,它會恢復為可放置對象。 我更喜歡關閉並停用可拖動對象回到其原始容器。
我的代碼在下面,但我在 jsFiddle 上提供了一個示例。
HTML
<div id="origin">
<div id="draggable" class="ui-widget-content">
<p>I revert when I'm not dropped</p>
</div>
</div>
<div id="droppable" class="ui-widget-header">
<p>Drop me here</p>
</div>
JavaScript
$(function() {
$("#draggable").draggable({
revert: function(dropped) {
var dropped = dropped && dropped[0].id == "droppable";
if(!dropped) alert("I'm reverting!");
return !dropped;
}
}).each(function() {
var top = $(this).position().top;
var left = $(this).position().left;
$(this).data('orgTop', top);
$(this).data('orgLeft', left);
});
$("#droppable").droppable({
activeClass: 'ui-state-hover',
hoverClass: 'ui-state-active',
drop: function(event, ui) {
$(this).addClass('ui-state-highlight').find('p').html('Dropped!');
},
out: function(event, ui) {
// doesn't work but something like this
ui.draggable.mouseup(function () {
var top = ui.draggable.data('orgTop');
var left = ui.draggable.data('orgLeft');
ui.position = { top: top, left: left };
});
}
});
});
使用jQuery 1.11.3和jQuery的UI 1.11.4 TESTED
演示: http : //so.lucafilosofi.com/revert-a-jquery-draggable-object-back-to-its-original-container-on-out-event-of-d/
$(function() {
$("#draggable").draggable({
revert : function(event, ui) {
// on older version of jQuery use "draggable"
// $(this).data("draggable")
// on 2.x versions of jQuery use "ui-draggable"
// $(this).data("ui-draggable")
$(this).data("uiDraggable").originalPosition = {
top : 0,
left : 0
};
// return boolean
return !event;
// that evaluate like this:
// return event !== false ? false : true;
}
});
$("#droppable").droppable();
});
我不確定這是否適用於您的實際使用,但它適用於您的測試用例 - 在http://jsfiddle.net/sTD8y/27/更新。
我只是做了這樣的內置還原,只有在項目之前沒有被丟棄的情況下才使用。 如果它已被刪除,則還原是手動完成的。 您可以通過檢查實際的 CSS 屬性來調整它以根據計算出的偏移量設置動畫,但我會讓您嘗試一下,因為它很大程度上取決於可拖動對象的 CSS 及其周圍的 DOM 結構。
$(function() {
$("#draggable").draggable({
revert: function(dropped) {
var $draggable = $(this),
hasBeenDroppedBefore = $draggable.data('hasBeenDropped'),
wasJustDropped = dropped && dropped[0].id == "droppable";
if(wasJustDropped) {
// don't revert, it's in the droppable
return false;
} else {
if (hasBeenDroppedBefore) {
// don't rely on the built in revert, do it yourself
$draggable.animate({ top: 0, left: 0 }, 'slow');
return false;
} else {
// just let the built in revert work, although really, you could animate to 0,0 here as well
return true;
}
}
}
});
$("#droppable").droppable({
activeClass: 'ui-state-hover',
hoverClass: 'ui-state-active',
drop: function(event, ui) {
$(this).addClass('ui-state-highlight').find('p').html('Dropped!');
$(ui.draggable).data('hasBeenDropped', true);
}
});
});
如果您想將元素恢復到源位置(如果它沒有被放置在#droppable
元素內),只需在腳本的開頭(而不是位置)保存可拖動元素的原始父元素,如果您驗證它不是放入#droppable
,然后將#draggable
的父元素恢復到這個原始元素。
所以,替換這個:
}).each(function() {
var top = $(this).position().top;
var left = $(this).position().left;
$(this).data('orgTop', top);
$(this).data('orgLeft', left);
});
有了這個:
}).each(function() {
$(this).data('originalParent', $(this).parent())
});
在這里,您將擁有可拖動元素的原始父元素。 現在,您必須在精確的時刻恢復它的父級。
每次將元素從 droppable 中拖出時都會調用drop
,而不是在停止處。 所以,你添加了很多事件回調。 這是錯誤的,因為您從不清除mouseup
事件。 一個可以掛鈎回調並檢查元素是否被放置在#droppable
元素內部或外部的好地方是revert
,並且您現在正在執行此操作,因此,只需刪除drop
回調即可。
當元素被放下,並且需要知道它是否應該被還原時,你肯定知道在新的拖動開始之前你不會有來自用戶的任何其他交互。 因此,使用您用來知道它是否應該恢復或知道的相同條件,讓我們用以下代碼片段替換此alert
:將父元素恢復到原始 div,並從draggable
內部重置originalPosition
。 該originalPosition
廣告載體在時間設置好的_mouseStart
,因此,如果您更改元素的擁有者,你應該重新設置,以使復歸走的動畫到適當的位置。 因此,讓我們將其設置為{top: 0, left: 0}
,使動畫轉到元素的原點:
revert: function(dropped) {
var dropped = dropped && dropped[0].id == "droppable";
if(!dropped) {
$(this).data("draggable").originalPosition = {top:0, left:0}
$(this).appendTo($(this).data('originalParent'))
}
return !dropped;
}
就是這樣! 你可以在這里檢查這個工作: http : //jsfiddle.net/eUs3e/1/
考慮到,如果在任何 jQuery 的 UI 更新中, revert
或originalPosition
的行為發生變化,您將需要更新代碼以使其工作。 請記住這一點。
如果您需要一個不使用對 ui.draggable 內部調用的解決方案,您可以使您的body
成為一個可放置的元素,其greedy
選項定義為false
。 你必須確保你的body
元素全屏顯示。
祝你好運!
如果有人感興趣,這是我對問題的解決方案。 它完全獨立於 Draggable 對象工作,而是使用 Droppable 對象上的事件。 它工作得很好:
$(function() {
$(".draggable").draggable({
opacity: .4,
create: function(){$(this).data('position',$(this).position())},
cursor:'move',
start:function(){$(this).stop(true,true)}
});
$('.active').droppable({
over: function(event, ui) {
$(ui.helper).unbind("mouseup");
},
drop:function(event, ui){
snapToMiddle(ui.draggable,$(this));
},
out:function(event, ui){
$(ui.helper).mouseup(function() {
snapToStart(ui.draggable,$(this));
});
}
});
});
function snapToMiddle(dragger, target){
var topMove = target.position().top - dragger.data('position').top + (target.outerHeight(true) - dragger.outerHeight(true)) / 2;
var leftMove= target.position().left - dragger.data('position').left + (target.outerWidth(true) - dragger.outerWidth(true)) / 2;
dragger.animate({top:topMove,left:leftMove},{duration:600,easing:'easeOutBack'});
}
function snapToStart(dragger, target){
dragger.animate({top:0,left:0},{duration:600,easing:'easeOutBack'});
}
它與還原原點有關:在拖動對象時設置原點:只需使用$(this).data("draggable").originalPosition = {top:0, left:0};
例如:我這樣使用
drag: function() {
var t = $(this);
left = parseInt(t.css("left")) * -1;
if(left > 0 ){
left = 0;
t.draggable( "option", "revert", true );
$(this).data("draggable").originalPosition = {top:0, left:0};
}
else t.draggable( "option", "revert", false );
$(".slider-work").css("left", left);
}
我找到了另一種簡單的方法來處理這個問題,你只需要屬性“connectToSortable:”來拖動,如下面的代碼:
$("#a1,#a2").draggable({
connectToSortable: "#b,#a",
revert: 'invalid',
});
PS:更多細節和例子
如何使用 jQuery 在源區域和目標區域之間移動可拖動對象
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.