Categories:

### Detecting a swipe (left, right, top or down) using touch

Swiping in touch is the act of quickly moving your finger across the touch surface in a certain direction. There is currently no "`onswipe`" event in JavaScript, which means it's up to us to implement one using the available touch events, plus define just when a swipe is a, well, "swipe".

Lets first define when a movement across the touch surface should be considered a swipe. There are two variables at play here- the distance traveled by the user's finger on the x or y-axis from `touchstart` to `touchend`, and, the time it took. Based on these two factors, we can decide whether that action qualifies as a swipe and in what direction.

With that said, lets put ideas into action and see how to go about detecting a swipe right (from left to right). Once we can do that, detecting swipe in the other 3 directions is pretty much identical. For this exercise we'll stipulate that a right swipe has occurred when the user has moved his finger across the touch surface a minimum of 150px horizontally in 200 ms or less from left to right. Furthermore, there should be no more than 100px traveled vertically, to avoid "false positives" whereby the user swipes diagonally across, which we don't want to qualify as a swipe right.

Example (mouse simulation added for non touch devices):

Swipe Me

```<script>

var touchsurface = document.getElementById('touchsurface'),
startX,
startY,
dist,
threshold = 150, //required min distance traveled to be considered swipe
allowedTime = 200, // maximum time allowed to travel that distance
elapsedTime,
startTime

function handleswipe(isrightswipe){
if (isrightswipe)
touchsurface.innerHTML = 'Congrats, you\'ve made a <span style="color:red">right swipe!</span>'
else{
touchsurface.innerHTML = 'Condition for right swipe not met yet'
}
}

touchsurface.innerHTML = ''
var touchobj = e.changedTouches[0]
dist = 0
startX = touchobj.pageX
startY = touchobj.pageY
startTime = new Date().getTime() // record time when finger first makes contact with surface
e.preventDefault()
}, false)

e.preventDefault() // prevent scrolling when inside DIV
}, false)

var touchobj = e.changedTouches[0]
dist = touchobj.pageX - startX // get total dist traveled by finger while in contact with surface
elapsedTime = new Date().getTime() - startTime // get time elapsed
// check that elapsed time is within specified, horizontal dist traveled >= threshold, and vertical dist traveled <= 100
var swiperightBol = (elapsedTime <= allowedTime && dist >= threshold && Math.abs(touchobj.pageY - startY) <= 100)
handleswipe(swiperightBol)
e.preventDefault()
}, false)

</script>

<div id="touchsurface">Swipe Me</div>```

Inside `touchend`, we check that the dist traveled from `touchstart` to `touchend` is a positive number above the specified threshold value (ie: 150), since in a right swipe, that dist should always be positive based on the equation used (versus negative for a left swipe). At the same time, we make sure any vertical lateral movement traveled is less than 100px to weed out diagonal swipes. Since the vertical movement can occur either above the starting touch point or below, we use `Math.abs()` when getting the absolute vertical dist traveled so both scenarios are covered when comparing it to our vertical threshold value of 100.

### A generic swipe detecting function

Now that we got right swipe down, lets create a more generic function that detects swiping in either of the 4 directions (left, right, up, or down):

```function swipedetect(el, callback){

var touchsurface = el,
swipedir,
startX,
startY,
distX,
distY,
threshold = 150, //required min distance traveled to be considered swipe
restraint = 100, // maximum distance allowed at the same time in perpendicular direction
allowedTime = 300, // maximum time allowed to travel that distance
elapsedTime,
startTime,
handleswipe = callback || function(swipedir){}

var touchobj = e.changedTouches[0]
swipedir = 'none'
dist = 0
startX = touchobj.pageX
startY = touchobj.pageY
startTime = new Date().getTime() // record time when finger first makes contact with surface
e.preventDefault()
}, false)

e.preventDefault() // prevent scrolling when inside DIV
}, false)

var touchobj = e.changedTouches[0]
distX = touchobj.pageX - startX // get horizontal dist traveled by finger while in contact with surface
distY = touchobj.pageY - startY // get vertical dist traveled by finger while in contact with surface
elapsedTime = new Date().getTime() - startTime // get time elapsed
if (elapsedTime <= allowedTime){ // first condition for awipe met
if (Math.abs(distX) >= threshold && Math.abs(distY) <= restraint){ // 2nd condition for horizontal swipe met
swipedir = (distX < 0)? 'left' : 'right' // if dist traveled is negative, it indicates left swipe
}
else if (Math.abs(distY) >= threshold && Math.abs(distX) <= restraint){ // 2nd condition for vertical swipe met
swipedir = (distY < 0)? 'up' : 'down' // if dist traveled is negative, it indicates up swipe
}
}
handleswipe(swipedir)
e.preventDefault()
}, false)
}

//USAGE:
/*
var el = document.getElementById('someel')
swipedetect(el, function(swipedir){
swipedir contains either "none", "left", "right", "top", or "down"
if (swipedir =='left')
})
*/```

`swipedetect()` accepts two parameters, the element to bind the touch events to, plus a function to execute when a swipe has occurred. The function parameter "`swipedir`" tells you the type of swipe that was just made with five possible values: "none", "left", "right", "top", or "down".

The below uses the `swipedetect()` function to show a "left", "right", "top", or "down" background image (overlaid on top of a default background image) depending on the swipe that has just occurred:

Example (mouse simulation added for non touch devices):

Swipe Me

The code used is:

```window.addEventListener('load', function(){
var el = document.getElementById('touchsurface2')
var inner = document.getElementById('inner')
var hidetimer = null
swipedetect(el, function(swipedir){
if (swipedir != 'none'){
clearTimeout(hidetimer)
var bgimage = swipedir + 'arrow.png' // naming convention is "leftarrow.png", "rightarrow.png" etc
inner.style.background = 'transparent url(' + bgimage + ') center center no-repeat'
hidetimer = setTimeout(function(){ // reset background image after 1 second
inner.style.background = ''
}, 1000)
}
})
}, false)```

The HTML markup is:

```<div id="touchsurface2">
<div id="inner">
Swipe Me
</div>
</div>```

We bind `swipedetect()` to "`#touchsurface2`", and whenever a valid swipe has occurred inside it, we change the "`#inner`" DIV's background image accordingly to reflect the type of swipe that has just occurred.

Partners