Stopping scroll when dragging on touch devices - javascript

I have the following drag-and-drop list component which works exactly as it should with mouse based events and should work that way with touch events but unfortunately while the touch events are starting to drag the list item the screen scrolls at the same time (making the drag pretty ineffectual).
component example
github source
What i'd like to know is what is the most effect ways to prevent this scroll event from taking place. This code was written using the Ember framework but a JS-specific answer is fine.

You can prevent the default behaviour:
$(".handle").on('touchstart',function(ev) {ev.preventDefault();})

Related

Enable page scrolling on <canvas> element

Currently a canvas element (which is built by a third party) on my webpage is intercepting drag events (because it assumes you want to drag something within the canvas), but this can "trap" the user within the canvas, especially if they zoomed in on it on mobile. I want the user to be able to scroll/swipe up and down on the canvas to reach the rest of the page above and below it, just like it were any other HTML element. They should be able to click into the canvas still, I just don't want the canvas to intercept regular page scrolling.
EDIT: I was able to find wheel and mousewheel events in the third-party code and remove them from the canvas object, resolving the issue for desktop users. Which event would be relevant for mobile users? I tried removing touchmove without success.
your issue seems to be that you're not correctly differentiating between scrolling and dragging.
I suggest you only prevent the default scrolling when the dragging actually takes place

drag drop with scroll in mobile issue

check code http://liveweave.com/ExmKkE
i have both scrollable and droppable object , problem i that when i try to scroll in mobile device object starts dragging how to stop dragging behaviour when scrolled
see below link :http://liveweave.com/ExmKkE
is it possible to stop vertical drag drop or any better way to overcome it
Use the Quo.js , it will fit your needs. Probably you will use the hold method.
Or if you don't want to use, this answer might be the best for you. Trigger Click-and-Hold Event

Preventing iPad top page drag

I'm trying for numerous days to solve the following issue.
I have a menu located on the top of the page which needed to be open using swipedown event (I'm using Hammer.js jQuery version).
Problem is, every time I try to interact using swipes I either scroll the page (swipeup) or pulling the page down same as described in the following question.
Here is what I've tried so far:
overflow: hidden; on the body element with an inner container with overflow: auto, swipe on top element still triggered document scroll.
Setting preventDefault on the document also disabled lower elements events in the DOM hierarchy and by that I had no swipe events working in the page.
Also tried using stopPropagation on the actual element when the event occurs, to prevent the bubbling up the chain for the event, the result cause the object to not respond to the events (swipes) and document scroll worked with no problems.
Any ideas how can I still keep page scroll but also when using common gestures, such as swipedown/swipeup, on specific elements that the element only will be affected?
Here is an example using JSFiddle, to better demonstrate the issue.
Would appreciate ideas/thoughts
I don't know if this will help, but I've always liked to use drag more than swipe. Using Hammer on my projects, swipes were a bit finicky. And from a UX standpoint, drag feels instantaneous vs a swipe. Much like, mousedown vs mouseup/click. So in instances where it's appropriate, and I believe in the case of showing swipey menu it is, I'd opt for drag.
Replacing your example with drag rather than swipe, and also using CSS transition, -webkit-transition, rather than jQuery's animate (drag will trigger like a mousemove, vs a click or a mouseup) seemed to make it work.
Hammer('.nav').on('dragdown', function(e){
e.gesture.preventDefault()
$(".blue").html("down")
$('.nav').css({"top":"0px"});
})
.on('dragup', function(e){
e.gesture.preventDefault()
$(".blue").html("dragup")
$('.nav').css({"top":"-150px"});
});
//Added in CSS, for .nav
.nav {-webkit-transition:0.5s top;}
Example
This does still have the page overscroll. A preventDefault() on document.ontouchstart would could fix that but that breaks scrolling. You might be able to do a selective preventDefault() by checking the scrollOffset perhaps. But I guess in the long run, I'd recommend something like iScroll.
Example
Also maybe tweak the hitbox for the drag to be a bit larger. Which I did in the last example. I attached the dragdown event on the document instead of the "menu" so the menu doesn't have to be visibly bigger.
Hammer(document).on("dragdown",function(e){
//calculate ratio of first touch from top
var pos=e.gesture.startEvent.center.pageY/window.innerHeight
if(pos<0.2){ //drag occurs in the first 20% of the screen
menu.style.marginTop="0px" //or animate here
e.gesture.preventDefault()
e.gesture.stopPropagation();
}
})
You should use the preventDefault function of the orginal gesture, to stop the browsers default behaviour, see here: https://github.com/EightMedia/hammer.js/wiki/Event-delegation-and-how-to-stopPropagation---preventDefaults
When you have a div element, on which you want to register swipe events, you would do the following:
$('#swipeDiv').hammer().on("swipe", function(ev) { ev.gesture.preventDefault(); });
That should prevent the scrolling of the page, but only if the swipe happens on the div element.

Drag/Touchmove Event with constant DOM Manipulation

I am looking to implement some Mobile Components using native Javascript and AngularJS.
While, I was working on creating a Pull To Refresh directive for AngularJS, I used touchmove event on a UL list. I was trying to pull a hidden div on top of a list with custom models to show status message.
I used touchmove event on the UL to create an effect of pulling by changing CSS3 translate property for the div. I was facing issue that the transition was happening after I finish touching the screen but not while I was dragging my touch.
Please help and throw in more details about the touchmove event.
Touch events
First of all, if you work on mobile devices and know a little about javascript you should write your own functions for the specific things that you need.So don't use libraries like angular, jquery or whatever ... it's only performance loss.
all you need is:
document.addEventListener('touchstart',ts,false);
document.addEventListener('touchmove',tm,false);
document.addEventListener('touchuend',te,false);
& to test:
document.addEventListener('mousedown',ts,false);//set mouseISDown to true
document.addEventListener('mousemove',tm,false);//check if mouse is down
document.addEventListener('mouseup',te,false);//set mouseISDown to false
css
Use translate3d() as it activates the gpu hardware acceleration. not just translate()
As your question is not very specific i can't add more info right now but...
Here are some examples using touch/mousemoves they may help you
Swipe & fastclick
http://jsfiddle.net/uRFcN/
https://stackoverflow.com/a/17567696/2450730
Radial Menu
http://jsfiddle.net/yX82S/
Slider
http://jsfiddle.net/LxX34/11/
Some UI elements
http://cocco.freehostia.com/scripts/SnapLightMT%20v0.2%20by%20cocco%20(1).html
try to swipe the main content or mousedown drag left right.
code.
http://cocco.freehostia.com/scripts/highlight.html
There is also a css trick that allows you to use the native scroll without the annoyng whole page move..So you don't have to use a library to scroll.
css
.scrollable{-webkit-overflow-scrolling:touch;}
.scrollable,.scrollable>div{width:100%;height:100%;overflow:auto;}
.scrollable>div>div{min-height:101%;}
html
<div class="scrollable"><div><div></div></div></div>

how do I recreate the sencha style gesture scroll for lists and content?

So... I am working on an interaction design project and I want to create a sencha-style gesture scroll for content areas. The way I've done it so far, is to attach touchmove/start/end events to the content area, and it translateY's the contents. It works in on desktop with mousemove/up/down events, but it jumps around like crazy with touch. I'm not sure whats wrong.. here is a link to a prototype.
**requires webkit.
http://apps.omorphos.com/gesture-scroll
I think it is an issue with the event response, but I tried and haven't been able to nail it down. Any help is greatly appreciated!
So, I figured this out.
What I was doing was attaching the touch event to the list tag itself.. and, that works fine on desktop with mouse events; however, with touch, the target changes and touchend doesn't fire properly.
So, what I did, and what I believe sencha does, ... and I had originally implemented but went in a different direction... is have an absolutely positioned element with a transparent background color floating above the element that will be manipulated. All of the touch events will be captured by that DIV and then the elements below can be manipulated without losing the event data.
In the new version I used HammerJs ... more info: http://eightmedia.github.io/hammer.js/
but i'm pretty sure you could just use standard events; but the good thing about hammer js, is that it will translate touch events to mouse events for testing in the browser, this also means making the coordinates for touch the same as mouse, so you can access mouse event coords via
e.gesture.touches[0].pageX
e.gesture.touches[0].pageY
which let's you write less code.
Part 2:
Additionally... part of the issue is... how do you click on the content/components(e.g. links) below the screen.
How you do this... is you take the coords from the event handler and pass them through this native Javascript function...
var a = document.elementFromPoint(x, y);
this will return the dom element. and all you have to do is trigger the click/tap event.
Which would be great, except it will pick the element with the highest z-index.. so that is your screen obj(the one that is capturing all of the touch events). So, what you need to do, is hide the screen after a tap is registered, and then execute this function 200ms later, and then bring back the screen to capture whatever events.
You can do this with this function...
$(theScreen).on('tap', function(e){
screen.hide();
var hit = document.elementFromPoint(e.gesture.touches[0].pageX, e.gesture.touches[0].pageY);
$(hit)[0].tagName !=="A" || $(hit).trigger('click');
setTimeout(function(){screen.show()},300);
});
And, that is how I solved it!
My code is not super annotated, but you can find it at the link below:
Updated example:
http://apps.omorphos.com/gesture-scroll/v2/

Categories

Resources