views:

1551

answers:

2

So, I'm looking to implement the ability for a plugin I wrote to read a touch "swipe" from a touch-capable internet device, like an iPhone, iPad or android.

Is there anything out there? I'm not looking for something as full as jQtouch, though was considering reverse engineering the code I would need out of it.

Any suggestions on the best way to approach this? A snippet of code already available?

Addendum: I realize in hindsight the solution won't strictly be jQuery, as I'm pretty sure there aren't any built-in methods to handle this. I would expect standard Javascript to find itself in the answer.

+6  A: 
(function($) {
$.fn.swipe = function(options) {
    // Default thresholds & swipe functions
    var defaults = {
        threshold: {
            x: 30,
            y: 10
        },
        swipeLeft: function() { alert('swiped left') },
        swipeRight: function() { alert('swiped right') },
        preventDefaultEvents: true
    };

    var options = $.extend(defaults, options);

    if (!this) return false;

    return this.each(function() {

        var me = $(this)

        // Private variables for each element
        var originalCoord = { x: 0, y: 0 }
        var finalCoord = { x: 0, y: 0 }

        // Screen touched, store the original coordinate
        function touchStart(event) {
            console.log('Starting swipe gesture...')
            originalCoord.x = event.targetTouches[0].pageX
            originalCoord.y = event.targetTouches[0].pageY
        }

        // Store coordinates as finger is swiping
        function touchMove(event) {
            if (defaults.preventDefaultEvents)
                event.preventDefault();
            finalCoord.x = event.targetTouches[0].pageX // Updated X,Y coordinates
            finalCoord.y = event.targetTouches[0].pageY
        }

        // Done Swiping
        // Swipe should only be on X axis, ignore if swipe on Y axis
        // Calculate if the swipe was left or right
        function touchEnd(event) {
            console.log('Ending swipe gesture...')
            var changeY = originalCoord.y - finalCoord.y
            if(changeY < defaults.threshold.y && changeY > (defaults.threshold.y*-1)) {
                changeX = originalCoord.x - finalCoord.x

                if(changeX > defaults.threshold.x) {
                    defaults.swipeLeft()
                }
                if(changeX < (defaults.threshold.x*-1)) {
                    defaults.swipeRight()
                }
            }
        }

        // Swipe was canceled
        function touchCancel(event) { 
            console.log('Canceling swipe gesture...')
        }

        // Add gestures to all swipable areas
        this.addEventListener("touchstart", touchStart, false);
        this.addEventListener("touchmove", touchMove, false);
        this.addEventListener("touchend", touchEnd, false);
        this.addEventListener("touchcancel", touchCancel, false);

    });
};
})(jQuery);


$('.swipe').swipe({
 swipeLeft: function() { $('#someDiv').fadeIn() },
 swipeRight: function() { $('#someDiv').fadeOut() },
})

and this is how you detect iphone

if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))) {
     if (document.cookie.indexOf("iphone_redirect=false") == -1) window.location = "path to iphone page";
}
XGreen
Awesome! I'm going to try this and then update the post, hopefully with a chosen answer.
dclowd9901
Worked brilliantly. I changed it up a bit so that it could be initialized through my plugin, but it's a great bit of code. Thanks much!
dclowd9901
The swipe plugin for jQuery can be found herehttp://plugins.jquery.com/project/swipe
Peder Rice
Both jSwipe and James Lin's solution work reasonably well for that one use case - "i want to detect a touch and drag that exceeds a given length". However this does not fully simulate native iOS/Android behavior, which is far more complex. For one, each solution cancels the default behavior of the touch move - what if you want the "swiped" element to move as you swipe (i.e. pan) instead of waiting for the swipe to end? Or if a short, fast swipe should be equal to a longer, slower swipe? Touch gestures are more about inertia and momentum than mere movement. A good solution is still missing.
Oskar Austegard
+1  A: 

Have a look at the following demo, requires only jQuery, not other plugins used. http://james.limsbros.com/2010/09/27/javascript-swipe-demo-works-both-with-finger-ipad-and-mouse-pc/

James Lin