Swipe function for touch-devices in Vanilla JS
Tags: javascript
Published: 2020-08-17 15:20:04

When we need to implement **Swipe** functionality for touch devices, we usually use plugins. But we can write touch-swipe functionality in **Vanilla JS** which supports all the browsers without using any plugin.

##### First We will see the whole function and then we will break the function into small pieces and will talk about the pieces
```
var  Swipe  = (function () {
	function  Swipe(element) {
		this.xDown  =  null;
		this.yDown  =  null;
		this.element  =  typeof (element) ===  'string'  ?  document.querySelector(element) :  element;
		this.element.addEventListener('touchstart', function (evt) {
			this.xDown  =  evt.touches[0].clientX;
			this.yDown  =  evt.touches[0].clientY;
		}.bind(this), false);
	}
	
	Swipe.prototype.onLeft  =  function (callback) {
		this.onLeft  =  callback;
		return this;
	};
	Swipe.prototype.onRight  =  function (callback) {
		this.onRight  =  callback;
		return this;
	};
	Swipe.prototype.onUp  =  function (callback) {
		this.onUp  =  callback;
		return this;
	};
	Swipe.prototype.onDown  =  function (callback) {
		this.onDown  =  callback;
		return this;
	};
	
	Swipe.prototype.handleTouchMove  =  function (evt) {
		if (!this.xDown  ||  !this.yDown) {
			return;
		}
		var  xUp  =  evt.touches[0].clientX;
		var  yUp  =  evt.touches[0].clientY; 
		this.xDiff  = this.xDown  -  xUp;
		this.yDiff  = this.yDown  -  yUp;
	
		if (Math.abs(this.xDiff) !==  0) {
			if (this.xDiff  >  2) {
				typeof (this.onLeft) ===  "function"  && this.onLeft();
			} else  if (this.xDiff  <  -2) {
				typeof (this.onRight) ===  "function"  && this.onRight();
			}
		}

		if (Math.abs(this.yDiff) !==  0) {
			if (this.yDiff  >  2) {
				typeof (this.onUp) ===  "function"  && this.onUp();
			} else  if (this.yDiff  <  -2) {
				typeof (this.onDown) ===  "function"  && this.onDown();
			}
		}
		// Reset values.
		this.xDown  =  null;
		this.yDown  =  null;
	};
	
	Swipe.prototype.run  =  function () {
		this.element.addEventListener('touchmove', function (evt) {
			this.handleTouchMove(evt);
		}.bind(this), false);
	};
	
	return  Swipe;
}());
```

##### Lets first discuss about the inner `Swipe` function
```
function  Swipe(element) {
	this.xDown  =  null;
	this.yDown  =  null;
	this.element  =  typeof (element) ===  'string'  ?  document.querySelector(element) :  element;
	this.element.addEventListener('touchstart', function (evt) {
		this.xDown  =  evt.touches[0].clientX;
		this.yDown  =  evt.touches[0].clientY;
	}.bind(this), false);
}
```

This function has the same name as the Root `Swipe` function. Because of that, when we will call the root function, the inner `Swipe` function will be initiated. In this function we are setting up the `touchstart` event for the target element. And we are capturing the `clientX` and `clientY` values from the `touchstart` event and assigning those values to `xDown` and `yDown` properties.

##### Now we will add the functions for each swipe direction
```
Swipe.prototype.onLeft  =  function (callback) {
	this.onLeft  =  callback;
	return this;
};
Swipe.prototype.onRight  =  function (callback) {
	this.onRight  =  callback;
	return this;
};
Swipe.prototype.onUp  =  function (callback) {
	this.onUp  =  callback;
	return this;
};
Swipe.prototype.onDown  =  function (callback) {
	this.onDown  =  callback;
	return this;
};
```
##### Then we will add the function to detect the Swipe direction
```
Swipe.prototype.handleTouchMove = function (evt) {
	if (!this.xDown || !this.yDown) { return; } 
	var xUp = evt.touches[0].clientX; 
	var yUp = evt.touches[0].clientY; 
	this.xDiff = this.xDown - xUp; 
	this.yDiff = this.yDown - yUp; 
	//Swipe Left or Right 
	if (Math.abs(this.xDiff) !== 0) {
		if (this.xDiff > 2) {
			typeof (this.onLeft) === "function" && this.onLeft(); 
		} else if (this.xDiff < -2) {
			typeof (this.onRight) === "function" && this.onRight(); 
		} 
	}
	if (Math.abs(this.yDiff) !== 0) {
		if (this.yDiff > 2) {
			typeof (this.onUp) === "function" && this.onUp(); 
		} else if (this.yDiff < -2) {
			typeof (this.onDown) === "function" && this.onDown(); 
		} 
	}
	this.xDown = null;
	this.yDown = null; 
};
```
In this function, we are tracking the swipe distance and the swipe direction. Based on the swipe direction, we are calling the respective *swipe-direction* function: `onLeft`, `onRight`, `onUp` and `onDown`.

> **Note:** In the `if` conditions, we are checking if the distance is `> 2` or `< -2`, because it might happen that when the user swipes on a horizontal direction, there might also be a slight vertical movement. And for this movement, the vertical swipe functions will be triggered. That is why, we are checking if the swipe distance is `> 2` or `< -2` for an extra bit of safety.

#### The run function
```
Swipe.prototype.run  =  function () {
	this.element.addEventListener('touchmove', function (evt) {
		this.handleTouchMove(evt);
	}.bind(this), false);
};
```
Here, we are adding an event-listener for `touchmove` event for the target element.  The `handleTouchMove` function will be called once the `touchmove` event fires.

### How can we use this?

First we will create a new object of the function and provide the target element as the parameter
```
var swiper = new Swipe('your-target-element');
```
Then we will call any of the swipe directional functions (`onLeft`, `onRight`, `onUp` and `onDown`) as per our need and inside the callback function we will write our code
```
swiper.onLeft(function() {
	//Your code goes here
});
```

##### Finally run the function
```
swiper.run();
```
> ***Note:*** this function will work only in the touch devices. You can use browser's *Developer Tools* to switch device that supports touch events and can check the function in there.

>***Final Note:*** This is my first article, so there might be many mistakes. Also, I believe that this function can be improved in may ways. Any comment or suggestion is much appreciated.