Pregunta

I have a carousel that is working just fine for all browsers and all devices except for ipad/iphone. When I swipe the carousel, it will use jqueries easing and bounce several times before stopping. The only way to make it behave, as it does in all other browsers, is to have an alert message pop up after swiping, then it works perfectly.

[code]

$("#CarouselWrap").bind("touchmove", function(event){

if(navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)) {
    whichWayMovingX[1] = event.originalEvent.touches[0].pageX;
    whichWayMovingY[1] = event.originalEvent.touches[0].pageY;

}else{
    whichWayMovingX[1] = event.originalEvent.changedTouches[0].pageX;
    whichWayMovingY[1] = event.originalEvent.changedTouches[0].pageY;
}

if(whichWayMovingX[0] > whichWayMovingX[1]){
    if(navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)){
        alert("left");
        moveLeft();
    }else{
        moveLeft();
    }
}else{
    if(navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)){
        alert("right");
        moveRight();
    }else{
        moveRight();
    }
}

}); [/code]

The moveLeft and moveRight functions are used with the arrows on the left and right of the carousel, so I know that these work, but only for onclick events.

[code]

switch(amountToMove) {
    case -1011:
$("#CarouselFeed").animate({marginLeft: amountToMove},{duration: 'slow', easing: 'easeOutBack', wipe:'true'});

[/code]

Why would this code work so well for onclick, but not for touchmove?

I have tried to combine the binds of touchstart, touchend and touchmove - nada I have tried to use touchmove mousemove - diddlesquat I have tried to use a setTimeout thinking that I had to wait for the last event - nothing

Please help, this is driving me nuts.

¿Fue útil?

Solución

Found the solution via some code for addressing the default behavior of a swipe.

First, set up the listeners:

    if(document.getElementById("CarouselFeed")){
    $("#CarouselFeed").bind("touchstart", function(event){
        touchStart(event,"CarouselFeed")
    });

    $("#CarouselFeed").bind("touchend", function(event){
        touchEnd(event);
    });

    $("#CarouselFeed").bind("touchmove", function(event){
        touchMove(event);
    });
}

I found the following code on a web site, that thanked two other web sites for their code and just as that web site changed the code a little to suit their needs, I have done the same:

// TOUCH-EVENTS SINGLE-FINGER SWIPE-SENSING JAVASCRIPT
// Courtesy of PADILICIOUS.COM and MACOSXAUTOMATION.COM
// redefined a few things to make this applicable to our needs

// this script can be used with one or more page elements to perform actions based on them being swiped with a single finger

var triggerElementID = null; // this variable is used to identity the triggering element
var fingerCount = 0;
var startX = 0;
var startY = 0;
var curX = 0;
var curY = 0;
var deltaX = 0;
var deltaY = 0;
var horzDiff = 0;
var vertDiff = 0;
var minLength = 72; // the shortest distance the user may swipe
var swipeLength = 0;
var swipeAngle = null;
var swipeDirection = null;

// The 4 Touch Event Handlers

// NOTE: the touchStart handler should also receive the ID of the triggering element // make sure its ID is passed in the event call placed in the element declaration, like: //

var touchStart = function(event,passedName){
// disable the standard ability to select the touched object
// event.preventDefault();
// get the total number of fingers touching the screen
fingerCount = event.originalEvent.touches.length;
// since we're looking for a swipe (single finger) and not a gesture (multiple fingers),
// check that only one finger was used
if(fingerCount == 1){
    // get the coordinates of the touch
    startX = event.originalEvent.touches[0].pageX;
    startY = event.originalEvent.touches[0].pageY;
    // store the triggering element ID
    triggerElementID = passedName;
}else{
    // more than one finger touched so cancel
    touchCancel(event);
}
}

var touchMove = function(event){
event.preventDefault();
if ( fingerCount == 1 ){
    curX = event.originalEvent.touches[0].pageX;
    curY = event.originalEvent.touches[0].pageY;
}else{
    touchCancel(event);
}
}

var touchEnd = function(event){
// event.preventDefault();
// check to see if more than one finger was used and that there is an ending coordinate
if (fingerCount == 1 && curX != 0){
    // use the Distance Formula to determine the length of the swipe
    swipeLength = Math.round(Math.sqrt(Math.pow(curX - startX,2) + Math.pow(curY - startY,2)));
    // if the user swiped more than the minimum length, perform the appropriate action
    if(swipeLength >= minLength){
        caluculateAngle();
        determineSwipeDirection();
        processingRoutine();
        touchCancel(event); // reset the variables
    }else{
        touchCancel(event);
    }   
}else{
    touchCancel(event);
}
}

var touchCancel = function(event){
// reset the variables back to default values
fingerCount = 0;
startX = 0;
startY = 0;
curX = 0;
curY = 0;
deltaX = 0;
deltaY = 0;
horzDiff = 0;
vertDiff = 0;
swipeLength = 0;
swipeAngle = null;
swipeDirection = null;
triggerElementID = null;
}

var caluculateAngle = function(){
var X = startX-curX;
deltaX = X;
var Y = curY-startY;
var Z = Math.round(Math.sqrt(Math.pow(X,2)+Math.pow(Y,2))); //the distance - rounded - in pixels
var r = Math.atan2(Y,X); //angle in radians (Cartesian system)
swipeAngle = Math.round(r*180/Math.PI); //angle in degrees
if (swipeAngle < 0) {swipeAngle =  360 - Math.abs(swipeAngle);}
}

var determineSwipeDirection = function(){
if( (swipeAngle <= 45) && (swipeAngle >= 0) ){
    swipeDirection = 'left';
}else if( (swipeAngle <= 360) && (swipeAngle >= 315) ){
    swipeDirection = 'left';
}else if( (swipeAngle >= 135) && (swipeAngle <= 225) ){
    swipeDirection = 'right';
}else if( (swipeAngle > 45) && (swipeAngle < 135) ){
    swipeDirection = 'down';
}else{
    swipeDirection = 'up';
}
}

var processingRoutine = function(){
var swipedElement = document.getElementById(triggerElementID);
if( swipeDirection == 'left' ){
    moveLeft();
}else if( swipeDirection == 'right' ){
    moveRight();
}else if( (swipeDirection == 'up') || (swipeDirection == 'left') ){
    moveLeft();
}else if( (swipeDirection == 'up') || (swipeDirection == 'right') ){
    moveRight();
}else if( (swipeDirection == 'down') || (swipeDirection == 'left') ){
    moveLeft();
}else if( (swipeDirection == 'down') || (swipeDirection == 'right') ){
    moveRight();
}
}

One note, I have this swipe working on a carousel that has banners. In order for the links for the banners to work, you have to comment out the event.preventDefault() within the touchStart and touchEnd functions.

And that is all it takes

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top