I want to make a web page on mobile devices (both Android and iOS) with fingers swipe effect, but when I add event.preventDefault() into ontouchstart / ontouchmove / ontouchend callback functions the scroll bar of the web page is being disabled, it is a disaster :(
I made an ugly hack for this with scrollTop so that the page can be scrolled:
element.ontouchmove = function(event) {
event.preventDefault();
var oldScrollTop = document.body.scrollTop;
var dist = final_y - start_y // here start_y is pageY from touchstart and final_y is current pageY
document.body.scrollTop = oldScrollTop - dist > 0 ? oldScrollTop - dist : 0;
//...
}
It works now but I still want to know:
It is there any other better solutions about this?
Why we must use "preventDefault()" in the callback functions? what we have prevented by this?
Thanks.
Related
This is for touch devices. I have a list with scroll in which when I touch on a list element, it will get highlighted and when we remove the finger with out vertical movement, it will go to its details page. But when we swipe(may be more than 9px pixels towards up or down), this highlight should be gone.This means it is a swipe attempt and not a click attempt.
I am using .mousemove() function to achieve this. But the .mousemove() is creating excess CPU usage for the browser. I need to reduce CPU usage. So is there a way to kill the .mousemove() event once the mouse position moves more than 9 px vertically? And if we try to swipe again, this .mousemove() event should trigger again.
Below is my code. Here "mousedownPosY" is the y position of the mouse when we touch the screen. "newMouseupPosY" is the value we get while swiping. If their difference is more than 9px, it will be a swipe attempt and remove the highlight on the list item.
$scope.mousemove=function(index,e){
var newMouseupPosY = e.pageY;
var mouseDiff = Math.abs(mousedownPosY - newMouseupPosY);
if ((Math.abs(newMouseupPosY - mousedownPosY)) > 9) {
//do something
}
};
If any one have a better method than .mousemove() ,Please share.
Thanks in advance!!
For touch devices you can use Javascript touch event like touchstart,touchmove,touchend.
Try below code may be it will helpful for you.
var startY = 0,
curY = 0;
window.addEventListener('touchstart', onTouchStart);window.addEventListener('touchmove', onTouchMove);
function onTouchStart(event) {
startY = 0;
curY = 0;
startY = event.touches[0].pageY;}
function onTouchMove(event) {
curY = event.touches[0].pageY - startY;
if (Math.abs(curY) > 9) {
// do something
}}
When a user is on a touch screen device, I'd like to restrict diagonal scrolling - so the idea is to force scrolling one direction at a time - horizontal or vertical.
I've set up a JS Fiddle that detects if touch scrolling is enabled and I'm able to output the x and y coordinates. But I don't see an offset or anything and figure I need that to calculate the intended direction.
I know that apple uses a directionalLockEnabled that will restrict, so I'm wondering if something like this is available in Kendo. If not, maybe there's a way I can figure out which direction the user is intending to scroll in and 'freeze' the other coordinate.
A JS fiddle I created (relevant part in the dataBound method):
http://jsfiddle.net/dmathisen/tskebcqp/
(the relevant code only works on touch... but should work if you enable mobile emulation in dev tools)
Another issue is the amount of times the scroll event is triggered. When working, maybe I can set up a debounce to handle how often it's triggered.
If you want to use javascript for this fix, you can calcul the ranges of the X and Y moves.
For that with touch devices, set the start posi X and Y when touchstart and calcul the distances when touchmove
var touchY = touchX = 0;
$(document).delegate('.yourWrap', 'touchstart', function(e){
touchX = e.originalEvent.touches[0].pageX;
touchY = e.originalEvent.touches[0].pageY;
});
$(document).delegate('.yourWrap', 'touchmove', function(e){
if (Math.abs(touchX - e.originalEvent.touches[0].pageX)
> Math.abs(touchY - e.originalEvent.touches[0].pageY)) {
// Block overflow-y
} else {
// Block overflow-x
}
touchX = e.originalEvent.touches[0].pageX;
touchY = e.originalEvent.touches[0].pageY;
});
For wheel devices, compare delta
(e.wheelDeltaY/3 || -e.deltaY)
(e.wheelDeltaX/3 || -e.deltaX)
Am building a page for iOS 8 where I need to completely block built-in scrolling and scroll the page through javascript alone (Eg. using scrollTo() method).
I don't want to hide the scrollbars, just to block the scrolling action (seems like it's done through event.preventDefault() ) and implement scrolling in JavaScript.
Can this be done?
JavaScript has a scroll event, unfortunately it is not cancelable (i.e. event.preventDefault() does not work).
If however you're only using touch enabled devices and scrolling is done through touch the touchmove event will be fired upon scrolling, which is cancelable, using event.preventDefault(), and will prevent scrolling. Note that this also prevents other actions requiring touchmove such as zooming.
Another solution, which might look a bit glitchy on some devices, is to store the scroll position of the document at the place you want to lock it and go to those coordinates whenever a user is scrolling. Something like the following:
var locked = false,
posX = 0,
posY = 0;
var lock = function(){
//assign the current coordinates to the position variables
var doc = document.documentElement;
posX = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
posY = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
locked = true;
};
var unlock = function(){
locked = false;
};
document.addEventListener('scroll', function(e){
if(locked)
scrollTo(posX, posY);
});
A couple years ago I made a cordova/phonegap app using iScroll. At the time it helped me through some seriously bad scroll view issues.
You can disable scroll, force move to etc
Perhaps it could work for you.
I built a touch/mouse friendly jQuery plugin. It works on phones(ios, android...) and desktops browsers. But i have some issues with Windows 8 Chrome installed on laptop with touch screen. Unfortunately i dont have such a device and cant do any tests.Also IE10 works fine.
Let me explain you what i have inside(very simplified code):
1.Check is touch device:
base.isTouch = ("ontouchstart" in document.documentElement);
2.Get proper events
if(base.isTouch === true){
//use touch events:
"touchstart.owl",
"touchmove.owl",
"touchend.owl"
} else {
//usemouse events
"mousedown.owl",
"mousemove.owl",
"mouseup.owl"
}
3.Check touch events:
if(base.isTouch === true){
x = event.touches[0].pageX
y = event.touches[0].pageY
} else {
x = event.pageX
y = event.pageY
}
link to real code
I think problem with chrome is that detect my touch events but use mouse events instead and translate them to touch.
I can add mouse and touch events together:
$('elem').on('mousedown.owl touchstart.owl',func);
Which is OK but then i have a problem with event.touches[0].pageX
link to plugin landing page
Thanks!
Problem solved
To get mouse and touch events working together on windows 8 chrome with touchscreen i had to:
1.add two events on one element "touchstart.owl mousedown.owl"
2.check "event.touches":
if(event.touches){
x = event.touches[0].pageX
y = event.touches[0].pageY
} else {
x = event.pageX
y = event.pageY
}
To get mouse and touch events working together on windows 8 chrome with touchscreen i had to:
1.add two events on one element "touchstart.owl mousedown.owl"
2.check "event.touches":
if(event.touches){
x = event.touches[0].pageX
y = event.touches[0].pageY
} else {
x = event.pageX
y = event.pageY
}
The simplest solution is to include Touch Punch plug-in http://touchpunch.furf.com/
I did it for my project and it works well - U can test it, here is my project:
http://englishtotheworld.com/
On Safari, you can get the location of where the user touched the screen from event.pageX and event.pageY. However, on my Android browser, event.pageX and event.pageY are always 0. Is there any way to get the location of a touch event in the browser on Android?
This is from memory, since I don't own an Android device anymore, but I think it's right. At the very least, it should get you started in the right direction. Good luck.
var elem = document.getElementById('elem');
elem.addEventListener('touchend', function(e){
var pageX = e.changedTouches[0].pageX,
pageY = e.changedTouches[0].pageY;
}, false);