droppable 이벤트 종료시 jQuery 드래그 가능 객체를 원래 컨테이너로 되돌립니다.
나는 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>
자바 스크립트
$(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
$(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())
});
여기에는 드래그 가능 항목의 원래 부모 요소가 있습니다. 이제 정확한 순간에 부모를 복원해야합니다.
drop
is called every time the element is dragged out from the droppable, not at the stop. So, you're adding a lot of event callbacks. This is wrong, because you never clean the mouseup
event. A good place where you can hook a callback and check if the element was dropped inside or outside the #droppable
element, is revert
, and you're doing it right now, so, just delete the drop
callback.
When the element is dropped, and needs to know if it should be reverted or not, you know for sure that you'll not have any other interaction from the user until the new drag start. So, using the same condition you're using to know if it should revert or know, let's replace this alert
with a fragment of code that: restores the parent element to the original div, and resets the originalPosition
from the draggable
internals. The originalPosition
proeprty is setted at the time of _mouseStart
, so, if you change the owner of the element, you should reset it, in order to make the animation of revert go to the proper place. So, let's set this to {top: 0, left: 0}
, making the animation go to the origin point of the element:
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;
}
And that's it! You can check this working here: http://jsfiddle.net/eUs3e/1/
Take into consideration that, if in any jQuery's UI update, the behavior of revert
or originalPosition
changes, you'll need to update your code in order to make it work. Keep in mind that.
If you need a solution which doesn't make use of calls to the internals of ui.draggable, you can make your body
an droppable element with greedy
option defined as false
. You'll have to make sure that your body
elements take the full screen.
Good luck!
In case anyone's interested, here's my solution to the problem. It works completely independently of the Draggable objects, by using events on the Droppable object instead. It works quite well:
$(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'});
}
It's related about revert origin : to set origin when the object is drag : just use $(this).data("draggable").originalPosition = {top:0, left:0};
For example : i use like this
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);
}
I've found another easy way to deal with this problem, you just need the attribute " connectToSortable:" to draggable like as below code:
$("#a1,#a2").draggable({
connectToSortable: "#b,#a",
revert: 'invalid',
});
PS: More detail and example
How to move Draggable objects between source area and target area with jQuery
'Program Tip' 카테고리의 다른 글
요소에서 두 번째 클래스 이름을 얻는 방법은 무엇입니까? (0) | 2020.12.03 |
---|---|
노드가 n 개인 유 방향 그래프에서 최대 간선 수는 얼마입니까? (0) | 2020.12.03 |
SQL Management Studio의 시작 / 끝 블록에서 "스키마 만들기"를 사용할 수없는 이유는 무엇입니까? (0) | 2020.12.03 |
ActiveRecord 범위에서 주문 제거 (0) | 2020.12.03 |
이미지를로드 할 때 WPF에서 "리소스를 찾을 수 없음"예외 발생 (0) | 2020.12.03 |