Transfer dragged div to other connected sortable during animated scroll
So I am trying to transfer over a div from one connected sortable container to another using jQuery UI. This sounds simple although I'm trying to do this while the content area is sliding over to the next area (think iPad/iPhone springboard).
The problem is when dragging the div containers over, they lose there positioning, so the dragging over becomes 'jumpy' as it does not stay in one place.
Here is what I have so far: (try dragging a block over to the right and you will see the problem)
UPDATE: Na7coldwater has said to give a position:absolute; which has helped the issue, but the block still disappears during animation.
http://jsfiddle.net/Az5kw/16/
What I'm aiming for in the end is to have the blocks to be spaced out in a grid type layout with a maximum value, say 4 per area. Then, a new slide area should be created if necessary (e.g. there is no more space for the blocks, a 3rd slide area will appear). Obviously I'm along way off from this as I can't even figure out how to move the blocks from area to area in a stable, smooth way!
Been at this for over a week now and am getting 开发者_StackOverflow社区nowhere :/
If you know of a better, more stable way of approaching this while still using jQuery that would be amazing!
Any help would be really, really appreciated!
Many thanks
Use the start/stop events of the draggable to set/unset position:fixed
on the moving .block
.
This way you disassociate it from the containers (in terms of positioning) while dragging.
Add
start: function(event,ui){
$(this).addClass('in-orbit');
},
stop: function(event,ui){
$(this).removeClass('in-orbit');
}
to the options of the draggable, and a css rule
.in-orbit{
position:fixed!important;
}
demo at http://jsfiddle.net/gaby/tktGA/1/
A partial fix:
You can change position:relative
in your css to position:absolute
. This fixes the position issue when the scrolling finishes, but the position is still incorrect during the animation.
JSFiddle
I have a solution for you, but it is kind of a hack due to me not finding the events that I was wanting in the cycle plugin documentation... explanation forthcoming.
Ok, to explain your problem...what is happening is purely positional. When transitioning to the right, for instance, you are taking the block from the rightmost part of the container, and then immediately appending it to the right most part of the other container. Therefor you cannot see the block while the slide transitions through the containers, until the very end of the animation occurs. Same goes for the transition back.
Now to solve this problem...
The correct solution would be to have the cycle plugin have a "cycle" event that triggers every cycle of the animation (similar to the drag event on the jQuery UI draggable widget). In the callback to that event, you would update the position of the block to move along with the transition. If you can find this event, or modify the "cycle" source code to fire this type of event, I would strongly suggest you doing so, and applying this method. If you are looking in the source code, I'd start by looking for a setTimeout, setInterval, jQuery effect (slide maybe?), or jQuery animation in the source code.
Since I didn't see an event that was called every cycle, I had to fake it by using jQuery Animate function. When the page transition happens, I move the block to the opposite side of the container, and have it animate to the correct location (where you were setting it initially, minus half the width of the block so that it doesn't go outside the target container). Unfortunately, this method is completely dependent on timing of the animations.
Replace the $('.block') code with this, and you should be able to start playing with the values to get it how you want it.
$(".block").draggable({
drag: function(event, ui) {
if(ui.offset.left + ($(this).width()/2) > $(this).parent().width() && $(this).parent().get(0).id == 'areaOne'){
//console.log('out of bounds');
$('#next2').trigger('click');
var next = $(this).parent().next();
$(this).appendTo(next).css({
left: -200, //Starting position
top: ui.position.top
}).animate({
left : ui.position.left - $(this).width()/2
},1000); //This number is the animation time (in ms)
}
else if(ui.offset.left < 0 - ($(this).width()/2) && $(this).parent().get(0).id == 'areaTwo'){
// console.log('out of bounds');
$('#prev2').trigger('click');
var prev = $(this).parent().prev();
$(this).appendTo(prev).css({
left: $(this).parent().width()+100, //starting position
top: ui.position.top
}).animate({
left : ui.position.left + $(this).width()/2
},900); //animation time (in ms)
}
}
});
Hope this helps, and good luck!
精彩评论