Перетаскиваемый возврат, если он находится за пределами этого div и внутри других перетаскиваемых элементов (с использованием как недопустимых, так и допустимых параметров возврата)

На перетаскиваемых элементах пользовательского интерфейса ( http://jqueryui.com/demos/droppable/#revert) можно ли вернуть div, если он находится внутри одного div, а если нет внутри другого? например вот так

$( "#draggable" ).draggable({ revert: "valid", revert:"invalid" });

но это не сработает по очевидным причинам... могу ли я это сделать?


person Logan    schedule 20.05.2011    source источник
comment
Являются ли «действительные» и «недопустимые» элементы div как-то вложенными? Потому что иначе, конечно, это не могло бы быть в обоих div одновременно... :)   -  person chrisfrancis27    schedule 20.05.2011
comment
представьте большой ящик, а внутри него маленькие ящики. маленькие ящики можно перетаскивать, и если я вынесу их за пределы большого ящика, они вернутся обратно, если я перенесу их в другой маленький ящик, он также должен вернуться, но это та часть, которую я не могу сделать. Я попытался сделать все маленькие ящики еще одним выпадающим, но, поскольку они также находятся внутри большого ящика, он регистрируется как действительный, поэтому возврата не происходит. Также пробовал жадный, что я не мог заставить его работать.   -  person Logan    schedule 20.05.2011
comment
Предполагая, что атрибут revert может принимать любой селектор, не могли бы вы использовать что-то вроде revert: ".outside, .valid > div.invalid"? Предполагая, что элемент, обертывающий «действительный», имеет класс outside.   -  person chrisfrancis27    schedule 20.05.2011
comment
на самом деле это либо истина, либо ложь (действительна или недействительна), поэтому я думаю, что нет никакого способа сделать это так. Знаете ли вы, есть ли способ исключить область маленьких ящиков из области больших ящиков и назвать это действительным?   -  person Logan    schedule 20.05.2011
comment
Ах, боюсь, что нет... Никогда не пользовался выпадающими предметами! :)   -  person chrisfrancis27    schedule 20.05.2011


Ответы (1)


Ваше мышление было правильным, вы должны сделать маленькие ящики жадными выпадающими предметами и обработать на них событие drop. Сложность заключается в том, чтобы отменить операцию перетаскивания.

По умолчанию ваши перетаскиваемые объекты должны начинаться как revert:'invalid'. Вам не нужно ничего делать, если они перетаскиваются внутрь большого ящика, который в моем примере использует tolerance:'fit', поэтому маленькие ящики должны быть полностью внутри, чтобы их можно было принять.

Я сделал маленькие ящики жадными выпадающими с помощью tolerance:'touch', поэтому, если перетаскиваемый маленький ящик касается другого маленького ящика, он вызывает для него обработчик drag.

Чтобы отменить операцию перетаскивания из обработчика перетаскивания, вы можете сделать обходной путь, установив для перетаскиваемого элемента значение revert:true, что заставит его вернуться, даже если он был перетащен на принимающий выпадающий объект. Чтобы убедиться, что вы можете снова перетащить этот маленький квадрат, в его событии остановки перетаскивания вы должны сбросить revert:'invalid'. Событие stop будет срабатывать при каждом успешном сбросе, а если произойдет откат, то он сработает после завершения отката.

Вы можете попробовать живую демонстрацию здесь: http://jsfiddle.net/htWV3/1/.

HTML:

<div class="drop">
    <div class="drag"></div>
    <div class="drag"></div>
    <div class="drag"></div>
    <div class="drag"></div>
    <div class="drag"></div>
</div>

CSS:

.drop { display:inline-block; width:300px; height:200px; border:1px solid silver; background-color:whitesmoke; padding:10px; }

.drag { display:inline-block; width:30px; height:30px; border:1px solid silver; background-color:white; }

Javascript:

$('.drop').droppable({
    tolerance: 'fit'
});

$('.drag').draggable({
    revert: 'invalid',
    stop: function(){
        $(this).draggable('option','revert','invalid');
    }
});

$('.drag').droppable({
    greedy: true,
    tolerance: 'touch',
    drop: function(event,ui){
        ui.draggable.draggable('option','revert',true);
    }
});
person DarthJDG    schedule 22.05.2011
comment
Ты просто великолепен! Большое спасибо! - person Logan; 23.05.2011
comment
Спасибо за это. Можно ли как-то это сделать с помощью helper: 'clone' на перетаскиваемом элементе? - person mreq; 14.11.2011
comment
@PetrMarek: я не уверен, как вы хотите, чтобы это работало, если вы хотите, чтобы перетаскиваемый объект просто защелкивался вместо своего клона при действительном сбросе, вы можете просто добавить обработчик сброса в основной контейнер с возможностью сброса и установить позицию ui.draggable в ui.position, где он был выпущен. Вот демонстрация: jsfiddle.net/htWV3/231 - person DarthJDG; 14.11.2011
comment
Привет, извините, что возвращаю это, но как вы можете улучшить эту работу с сеткой? например, моя перетаскиваемая привязка к grid: [ 60, 60 ], но когда она возвращается после сброса, она не возвращается обратно в положение сетки, она всегда немного отключена. - person ChristopherStrydom; 13.04.2013
comment
Я только что понял, что это происходит только после второго перетаскивания одного и того же элемента. - person ChristopherStrydom; 13.04.2013
comment
Можно ли изменить размер этих div в сочетании с функцией перетаскивания? - person Pieter_Daems; 15.11.2013
comment
прежде всего большое спасибо. я многому научился из вашего ответа, который был связан с другим вопросом, где принятым ответом было использование другого плагина. я добавлю, что при использовании сетки я считаю, что мне лучше установить tolerance из greedy сбрасываемых на fit. иначе он не позволил бы мне попасть в точки сетки, которые касались жадного выпадающего. - person r14n; 05.09.2014