Online consulting also refers to a few examples, feeling that some ideas are too cumbersome, and they are also new to the front of the small white (last year), so in order to exercise their own js level, decided to simply encapsulate under their own ideas, including the following functions:
- Touch Start: Touch Start
- swipeLeft: Quick left pull
- swipeRight: Quick pull right
- swipeUp: Quick pull-up
- swipeDown: Fast drop-down
- dragVertical: Slide vertically
- dragHorizontal: Slide horizontally
- Drag: drag
- tag: tap
- longTag: Long press
- Touch End: Touch End
Briefly describe the principle
The main purpose is to judge the user's gesture through three major events (touch start, touch move, touch end), and then dispatch the corresponding event handler (custom).First, there are a few questions to be clear:
1. Tapping and long pressing events are not triggered at just one point. Due to different user's operation habits, several pixel offsets may occur when tapping. It seems that some mobile phones still have error values (not tested);
2. Events involving direction need to calculate the angle value, only the horizontal and vertical directions need to be calculated to get other directions.
Angle calculation:
As shown in the figure, the color part is vertical, the other is horizontal, point A is the starting point of touch start, point B is the finger, and x, y is the horizontal and vertical displacement distance (absolute value).To make the calculation very simple, first deal with question 1 above. Since there is an error, let X or y be greater than a value before calculating the angle. This assumes that 4 (the larger the value, the less accurate the problem 1) will occur. When the finger displaces a distance >=4 in one direction, the angle will be calculated immediately. However, the angle is not actually calculated. Right triangle law, X and y are phases.The isochronism is 45 degrees, and the angle is less than 45 degrees when x > y (point B moves down vertically), that is, horizontally, and vice versa.Even if you don't take a 45 degree angle here, you can use the same principle.
//1. Judge the conditions for sliding horizontally across the screen: the x-axis must be shifted.The displacement distance is greater than 4, and at this time x > y
x !== 0 && x >= 4 && x > y
//2. Judge the conditions for sliding vertically across the screen: the y-axis must be shifted.Displacement distance is greater than 4, and Y > x at this time
y !== 0 && y >= 4 && x < y
//3. Judge the conditions for sliding across the screen to the right: when condition 1 is met
A.x - B.x < 0
//4. Judge the conditions for sliding across the screen to the left: when condition 1 is met
A.x - B.x > 0
//5. Judge the conditions for sliding up across the screen: when condition 2 is met
A.y - B.y < 0
//6. Judge the conditions for sliding down the screen: when condition 2 is met
A.y - B.y > 0
Here's the code. I wrote it a long time ago, and I'm lazy - let's not change this obscure code...The first time you write an article, the intersection begins. Preview Address
/*
Use
DJ.toucher('#div')
.on('touchStart', function(e) {
console.log('touchStart');
})
.on('swipeLeft swipeRight swipeUp swipeDown', function(e) {
console.log('...')
})
...
*/
;(function(w, d, factory) {
var fn = factory(w, d);
w.DJ = w.DJ || {};
w.DJ.toucher = w.DJ.toucher || fn;
})(this, document, function(w, d) {
"use strict";
function Djswipe(el) {
this.elem = d.querySelector(el) || {};
// Custom Event Library
this._events = this._events || {};
// Record Vertical or Horizontal Directions
this.dir = false;
// Handle long press timer
this.ltimer = null;
this.istouched = false;
}
Djswipe.prototype = {
events: ['touchStart', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'dragVertical', 'dragHorizontal', 'touchEnd', 'drag', 'tag', 'longTag'],
init: function() {
this.touch();
return this;
},
//Simulate on custom event binding, separated by multiple event spaces
on: function(evt, handler) {
var arrevts = evt.split(' '),
len = arrevts.length,
isFunction = typeof(handler) === 'function';
for(var i=0;i<len;i++) {
this._events[arrevts[i]] = this._events[arrevts[i]] || [];
isFunction && this._events[arrevts[i]].push(handler);
}
return this;
},
//Custom event triggers
trigger: function(evt, e, s) {
if (!!evt)
for (var i = 0; evt[i]; evt[i++].call(this.elem, e, s));
},
touch: function() {
var _t = this,
sx, sy,
disX, disY;
this.elem.addEventListener('touchstart', function(e) {
_t.dir = false;
_t.istouched = true;
_t.islongtag = false;
_t.startTime = new Date();
sx = e.targetTouches[0].pageX, sy = e.targetTouches[0].pageY;
// Start touching
_t.trigger(_t._events.touchStart, e);
_t.ltimer = setTimeout(function() {
// Long press
_t.istouched && _t.dir === false && (_t.trigger(_t._events.longTag, e),_t.islongtag = true);
}, 500);
}, false);
this.elem.addEventListener('touchmove', function(e) {
var mx = e.targetTouches[0].pageX,
my = e.targetTouches[0].pageY,
x, y;
disX = mx - sx, disY = my - sy;
x = Math.abs(disX), y = Math.abs(disY);
//Coordinates and displacement values, etc., to make it easy to get them directly from the outside and do other operations
var status = {
startx: sx,
starty: sy,
movex: mx,
movey: my,
disx: disX,
disy: disY
}
// level
if (x !== 0 && x >= 4 && x > y && _t.dir === false)
_t.dir = 0;
// vertical
if (y !== 0 && y >= 4 && x < y && _t.dir === false)
_t.dir = 1;
// Drag
_t.dir !== false && _t.trigger(_t._events.drag, e, status);
// Slide Horizontally and Vertically
_t.trigger(_t._events[['dragHorizontal', 'dragVertical'][_t.dir]], e, status);
}, false);
this.elem.addEventListener('touchend', function(e) {
_t.istouched = false;
_t.disTime = new Date() - _t.startTime;
clearInterval(_t.ltimer);
if (_t.disTime < 150) {
if (_t.dir === 0) {
// About
disX < 0 && _t.trigger(_t._events.swipeLeft, e);
disX > 0 && _t.trigger(_t._events.swipeRight, e);
}
if (_t.dir === 1) {
// Up and down
disY < 0 && _t.trigger(_t._events.swipeUp, e);
disY > 0 && _t.trigger(_t._events.swipeDown, e);
}
// Tap
_t.dir === false && _t.trigger(_t._events.tag, e);
} else {
// Handle extra gaps in tag, longtag
(_t.dir !== false || _t.dir === false && _t.islongtag === false) && _t.trigger(_t._events.touchEnd, e);
}
}, false);
}
};
return function(el) {
return new Djswipe(el).init();
}
});