Odd Draggable Behavior After Implementing Auto Scroll - javascript

I've implemented drag and drop using the jQuery UI draggable widget.
I'm now implementing auto scroll during drag operations. I set it up so that when you start to drag, gray overlays appear at the top and bottom of the browser window. When you drag into one of these overlays, the browser window starts to auto scroll.
You can see my test page at http://www.softcircuits.com/Client/scrolltest.html. Drag an item by dragging one of the crosshair icons on the left side.
But there's a problem: if you scroll to the bottom of the page, and then drag an item to the top overlay, it will scroll up as expected. However, for me, I get about half way up the page and the draggable helper won't go any higher. There's no way for me to drag all the way to the top of the page.
This most likely seems related to the Draggable widget. Is anyone able to see why this is happening? I'm using Google Chrome on Windows 7.

To be cross-browser compatible and to avoid wird behavior, I would recommend to use all JQueryUI draggable callbacks.
I read some days ago that the last version of Chrome has some really tricky problems with natives HTML5 draggable events.
For example, I have just checked your web page source code and you are using $('.drag-handle').on('drag', function(){...}); => You should use the drag callback.
I would also recommend to not use window as the scrollable container in your case. You should create a div to wrap all the tables contents and use it as a scroll container. I have already done this implementation in the past and it is working.
Don't forget to set the wrapper ID in the containment option durring the draggable widget creation.
If it always not working, you could also try to overwrite the helper position in the drag callback :
//Save the mouse position in global variables
$(document).mousemove(function(e){
window.mouseXPos = e.pageX;
window.mouseYPos = e.pageY;
});
$('[id^="drag-"]').each(function() {
$(this).draggable({
opacity: 0.7,
cursorAt: { top: 15, left: 50 },
scroll: true,
stop: function(){},
drag : function(e,ui){
//Force the helper position
ui.position.left = window.mouseXPos - $(this).draggable('option','cursorAt').left;
ui.position.top = window.mouseYPos- $(this).draggable('option','cursorAt').top;
});
});

Changing the draggable containment option from window to document worked for me.
$('.drag-handle').draggable({
...
containment: "document",
...
});
See: http://docs.jquery.com/UI/Draggable#option-containment

Related

Disable x or y snap in jQuery UI draggable

I have app where i need only snap element to top and bottom edges of parent element. I try to find how to do it in stack but i can't find it!
el.draggable({
start: function(){
var snapped = $(this).data('draggable').snapElements;
snapped.forEach(function(el){
el.width = 1000000;
el.left = -50000;
});
}
})
One approach is doing the snapping manually instead of relying on the draggable's functionality. E.g. you can disable the snapping and in your drag handle implement it by changing the object's position whenever it's close enough to whatever location you like.
Here's a solution for the similar request: Getting jQuery draggable to snap to specific grid

Using jQuery draggable() in a responsive environment…

I am working on a fairly typical image "reveal" effect using jQuery UI’s draggable() method; I’m having a lot of trouble making it work in a responsive environment:
http://codepen.io/ProfessorSamoff/pen/qEaNMM
As you’ll see, the reveal functionality works correctly at full size as well as when the browser window size is reduced. But the draggable handle doesn’t always snap to the proper position when the browser window is resized. (Although it does so when it’s clicked and dragged.)
Likewise, you’ll see that I have some commented code that checks against the browser window size:
if($(this).width() != width)
{
}
This works in order to get the draggable handle to the correct place when resizing the browser window, but it breaks the draggable functionality.
I have tried a few of the suggestions on Stack Overflow concerning draggable() and resizable(), but none of them work.
take a look here:
http://codepen.io/anon/pen/LEmgBP
javascript now appears in this way:
var $reveal = $(".reveal");
$reveal.draggable({
axis: "x",
containment: "parent",
iframeFix: true,
refreshPositions: true,
drag: function()
{
var position = $(this).position();
var parentWidth = $(this).parent().width();
var width = (position.left / parentWidth) * 100
$(".featured").width(width + "%");
}
});
$(window).resize(function() {
$reveal.css('left', $(".featured").width()+'px')
});
It's not elegant but it seems to work.
basically I did 2 things:
1) I've setted $(".featured") width with %
2) on windows resize I change the position of the cursor with
$reveal.css('left', $(".featured").width()+'px')
note: point 2) is a workaround but I didn't find any way to move the cursor programatically. Maybe using a library to emulate the drag event (like https://github.com/mattheworiordan/jquery.simulate.drag-sortable.js/blob/master/README.md) you could find something better

maintaining relative screen size of jquery ui draggable/resizable object on window resize

I have a web page with a couple div elements that are resizable and draggable through the jquery ui library.
$('#myDiv').draggable({ containment: "parent" }).resizable({ aspectRatio: true});
Dragging and resizing work fine, but I would like the divs to resize to maintain their relative size to the window as the window is resized. For example if drag div 1 to the top right and size it to 50% of the screen width, is there a way to maintain that sizing as the window resizes? I can't seem to find any options within jquery or jquery ui to allow me to force the elements to size based on percentage. Is there a way to do this with jquery, or do I need to write code that gets called on window resize that can handle this?
What I have done is following the answer of this question:
stackoverflow.com/questions/37328053/draggable-object-goes-outside-the-container-when-the-window-is-resized
What they propose is on stop the dragging event, convert to % positions you would like to keep, in the above exeample I converted left and top.
$('#myDiv').draggable({containment: "parent",
stop: function(e, ui) {
var percLeft = ui.position.left/ui.helper.parent().width()*100;
var percTop = ui.position.top/ui.helper.parent().height()*100;
ui.helper.css('left', percLeft + '%');
ui.helper.css('top', percTop + '%');
}
}).resizable({ aspectRatio: true});

Can stellar.js readjust element offsets on window resize?

Is there a way to reinitialize stellar.js on browser/window resize so that the element offsets get readjusted?
First of all, it sounds like you might be having an issue with horizontal alignment (assuming it's a vertical site). If so, it's likely that you only need to disable horizontal scrolling:
$.stellar({
horizontalScrolling: false
});
If this doesn't solve your issue, Stellar.js has an undocumented feature that allows you to refresh the plugin.
For example, let's assume you used Stellar.js like this:
$.stellar();
You can refresh it with the following:
$.stellar('refresh');
So, to refresh it on resize, you could do something like this:
$(window).resize(function() {
$.stellar('refresh');
});
Hopefully this should fix everything for you.
After a bit of sleuthing, I've figured this one out. In my case, I have 'slides', which contain my stellar elements, and they are sized to full width/height of the viewport. I needed to resize them for tablet orientation change.
$(window).resize(function(){
winHeight = $(window).height();
$("#scrollWrapper > div").height(winHeight);
// Find out all my elements that are being manipulated with stellar
var particles = $(window).data('plugin_stellar').particles;
// Temporarily stop stellar so we can move our elements around
// data('plugin_stellar') let's me access the instance of stellar
// So I can use any of its methods. See stellar's source code
$(window).data('plugin_stellar').destroy();
$.each(particles, function(i, el){
// destroy() sets the positions to their original PIXEL values.
// Mine were percentages, so I need to restore that.
this.$element.css('top', '');
// Once the loop is finished, re-initialize stellar
if(particles.length - 1 == i){
$(window).data('plugin_stellar').init();
}
});
});
If it doesn't matter that the elements get set to their original pixel values for left/top, then you can just call destroy & init one after the other:
$(window).data('plugin_stellar').destroy();
$(window).data('plugin_stellar').init();
If you instantiate stellar on an element (i.e., $("#element").stellar(); instead of $.stellar();) then replace "window" with your selector.
I also noticed odd offsets on mobiles that may be caused by the way Firefox/Chrome resizes the webview when scrolling down, when the location bar becomes visible again?
The answer to your question is in a section of the documentation: "Configuring everything":
// Refreshes parallax content on window load and resize
responsive: false,
So, this is false by default. To enable this, use .stellar( {responsive:true} )
The real question is... why is this disabled by default? It seemed to fix the problem I was noticing, except for iOS.

Draggable element in VML get stuck when size change (height, width) in IE 8

I'm having issue with VML (which I use as fallback for svg)
I use jQuery UI draggable to let user be able to move an element around. The problem occurs when I resize the image (which is a v:image) by changing the style attribute of height and width.
What happen at this point is that the element get stuck at the left top corner of it's container and cannot be dragged anymore.
A strange thing is that when I ask for the position (top, left) of the draggable element in the JavaScript console, I get value, and those values change when I click and drag - even though the element isn't visually moving...
Anyone run into this problem before?
Here's where I change then size of my element.
$($image)
.css({
'width' : zoomInPx_width + "px",
'height' : zoomInPx_height + "px"
});
The draggable is set pretty straight forward
$($image).draggable({
drag: function () { /*callback here*/ }
})
Finaly I manage to make this work.
Seems that VML crash on IE 8 when we change size of a draggable element. So, I had to destroy the element and recreate it from scratch when sliding occurs...
That's not really performant, but that's the only fix to work for me up here.
By the way, .detach() didn't work, you have to destroy it and recreate it from scratch.
You can get some info there too: http://www.acumen-corp.com/Blog/tabid/298/EntryId/26/Using-jqueryRotate-ui-draggable-and-resizable-images-in-IE7-IE8-and-any-other-browser.aspx
on my application I used this code:
var $cloned_image = $($image).clone().get(0);
$($image).remove();
// need add draggable again
$($cloned_image).draggable();
document.getElementById('k').appendChild($cloned_image);
$image = $cloned_image;

Categories