I need to capture Draggable events in order to apply animation whenever Drag Action get cancelled by user or offset get updated.
In particular this callbacks
onDraggableCanceled → DraggableCanceledCallback
Called when the draggable is dropped without being accepted by a DragTarget. [...]
void DraggableCanceledCallback (
Velocity velocity,
Offset offset
)
Signature for when a Draggable is dropped without being accepted by a DragTarget.
Used by Draggable.onDraggableCanceled.
Related
In Jquery UI.Sortable, We can specify delay to start the sort.
I want to know, if there is any event that is triggered once the delay(i.e.,ms) completed.
I tried all events in the API list, start, activate etc. but all the events are triggered when i start to move the item.
I want to trigger an event when i hold (click & hold) the item for n milliseconds.
The requirement is as follows:
set delay of 100ms
click & hold using mouse for less than 100ms, we can't move // That's working fine.
click & hold using mouse for greater than equal to 100ms, we can move. but until we can drag user doesn't know whether the selected item can able to move or not.
So after delay completed, need an intimation for that selected item can view different apart from other items.
Kindly provide any idea to proceed.
I think this is a problem with the understanding.
delay -
Time in milliseconds to define when the sorting should start. Adding a delay helps preventing unwanted drags when clicking on an element.
The item is always draggable, The delay is triggered only after you start dragging. It doesn't start if you click and hold the mouse, so there is no use of indicating the user that item is now draggable once they click and hold mouse because it does nothing.
The delay is set for n milliseconds after you start dragging - And the start event is triggered right after the delay. You can make use of start event to notify the user that the item is now dragging.
For example
<div class="sortable">
<div class="grabbable"></div>
<div class="grabbable"></div>
</div>
$('.sortable').sortable({
delay: 500,
start: function (e, ui) { // will be triggered after 500ms
ui.helper.addClass('highlight');
},
beforeStop: function (e, ui) {
ui.helper.removeClass('highlight');
}
});
Demo
If I scroll a page the currently dragged draggable stays in the same position. This leads to the finger not being above the draggable anymore. Is there any way in which I could update the position of a draggable to the current touch location without removing the draggable functionality?
My setup is rather complicated using iScrolls scrollTo method for Scrolling and jQuery-Ui-Touch Punch for touch support, but this should apply to other cases of draggable and touch/click position-mismatch as well.
update: function (event, ui) {
var data = $(this).sortable('toArray').toString();
//use ajax to update the position
}
I need to keep the scroll offset of an element in sync with another (the window actually) and I'm having trouble doing so during the inertial "roll off" phase of scrolling on Mobile Safari (iPad).
I have a couple of divs with position:fixed; overflow:hidden and I need to keep their scroll offset in sync with the window's one (meaning the entire body scroll.) Usually I'd code it like this (jQuery):
var $win = $(window),
$div1 = $(...)
$win.scroll(function() {
$div1.scrollTop($win.scrollTop())
})
But testing the interface on an iPad, I noticed that the div was not being updated neither during the touch phase, when you are dragging the virtual page with your finger, nor during the inertial phase, when you let go and the page slows down to a stop.
I solved it for the dragging phase by registering the handler for the touchmove event as well as the scroll one.
But I can't find a way to solve the problem for the inertial phase. The div stays still (and goes slowly out of sync with the rest of the page) until the inertial movement comes to a full stop, when the scroll event is finally fired and it skips into position.
Here's a working demo.
Try to scroll it on an iPad to see the "inertial scolling" problem. Unfortunately I couldn't get it to work on jsFiddle, due to the iPad's weird behaviour with iframe scrolling.
If I could just run a polling during that phase, I could keep a semblance of synchronization between the two elements. I've tried with setTimeout, setInterval, and requestAnimationFrame, but neither of them fires during the inertial scrolling phase. It seems like all Javascript stops during that phase.
Questions:
Is there any touch or scroll event fired during the inertial scrolling phase?
Is there any way to run a Javascript callback during that phase?
Is there a way to sync the scroll offset of two elements (either X or Y, not both) using CSS or some other technology other than JS?
OldDrunkenSailor beat me to suggesting iScroll.
Unfortunately, out of the box iScroll just replicates the same problem as native inertial scrolling -- there's no event handling during the inertial phase.
Here's a version of your demo with a monkey-patched iScroll to add a custom event that fires even during the inertial stage: https://dl.dropbox.com/u/15943645/scrollingdemo.html
Works great on my 2nd gen iPad.
JS:
// Disable touch events
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
// Patch iScroll for position change custom event
iScroll.prototype._oldPos = iScroll.prototype._pos;
iScroll.prototype._pos = function(x, y) {
this._oldPos(x, y);
if (this.options.onPositionChange) this.options.onPositionChange.call(this);
}
$(function() {
var $win = $(window),
$div_cols = $('#cols'),
$div_rows = $('#rows'),
$div_body = $('#body')
// attach scrolling sync handler and execute it once
function sync_scroll(e) {
$div_cols.scrollLeft(0 - $div_body.position().left);
$div_rows.scrollTop(0 - $div_body.position().top);
}
// initialize iScroll on wrapper div, with position change handler
var myScroll = new iScroll('iscroll_wrapper', {
bounce: false,
onPositionChange: sync_scroll
});
})
CSS:
#iscroll_wrapper {
position:absolute;
z-index: 1;
left: 168px;
top:77px;
bottom:0px;
right:0;
overflow:auto;
}
#body {
position:absolute;
z-index: 1;
width: 2046px;
height: 3376px;
}
Note only the body responds to touch events, but you can extend the technique to the rows and cols divs for the reverse relationship.
iOS actually freezes DOM manipulation and Javascript while inertial scrolling is happening. Here is a simple demo that I made to illustrate the difference between scrolling in a normal desktop environment vs the iPad: http://jsfiddle.net/notjoelshapiro/LUcR6/. This code only has this JS in it:
var num = 0;
function updateNum(){
num++;
$('#awesomeDiv').text(num);
}
$(window).scroll(updateNum);
On scroll it increments a number and displays it on the bottom of the page. You'll see that the scroll number at the bottom of the screen is only being incremented when the inertial scroll has stopped. If Javascript was acting in the background it wouldn't refresh until the scroll ended but the number should be incremented higher.
So to answer your questions specifically:
Is there any touch or scroll event fired during the inertial scrolling phase?
Negative, ghostrider.
Is there any way to run a Javascript callback during that phase?
See above.
Is there a way to sync the scroll offset of two elements (either X or Y, not both) using CSS or some other technology other than JS?
Not quite sure what you mean here, JS can do all of the math'ing that you need but it will have to be when inertial scroll has completed. To be honest though, this may be a symptom of tl;dr since I'm at work right now.
Have you looked at the iScroll library? It simulates intertial (or non-inertial) scrolling for touch and non-touch environments and gives you JS callbacks during/after "scroll" and "inertial scroll" and provides a lot of information that you can use to calculate where you are on the page.
Triggers when a scroll begins. Note that iOS devices freeze DOM manipulation during scroll, queuing them to apply when the scroll finishes. We're currently investigating ways to allow DOM manipulations to apply before a scroll starts.
http://jquerymobile.com/demos/1.0rc1/docs/api/events.html#/demos/1.0rc1/docs/api/events.html
Thats what they had to say under scroll start section
I am using CSS3 resize: vertical; to allow the user to resize a Div, and would like to be notified when this happens (so that I can adjust the size of other elements with Dart code if necessary).
How can I attach an event listener for the user resize event?
( DivElement.on.resize does not exist.)
When you want to observe event which is not listed under the on getter, you can use $dom_addEventListener to set event listener.
Thus, if you would like to use something like the unexisting divElement.on.resize, you can use :
divElement.$dom_addEventListener("resize", (e) {
// event occurs
});
That said, unlike click event, the resize event doesn't seem to be fired (even in javascript).
When you are dragging an element using the touch events (DnD on touch screens), how do you detect that the object that you are dragging is over another object?
With jQuery is easy, add "collide: 'block'" or "collide: 'flag'" when you create a draggable.
http://plugins.jquery.com/project/collidable
I haven't found any direct solution for this. One can have draggable element positioned "outside" dragging finger, but this didn't work in my case.
In my case, I had a grid-like element with fixed size child elements. Therefore it was easy to compare pageX/pageY of touchmove to the parent element and count the current element index by dividing the result with their dimensions.