大家讲道理2017-04-17 11:21:366楼
以前寫過一個庫,研究過這一問題(當然產品環境下還是用現成的解決方案比較好)
也看過成熟解決方案的代碼
很簡單,記錄位移,任意方向超過 10 就不是 tap 了。
某一方向 超過 30 就是 swipe,如果在 swipe 之前豎直方向位移大於 10 就判定爲 scroll
如果進入 swipe 狀態,就 preventDefault
如果時間超過一個數值(具體多少忘了,好象是 750?)就不是 swipe 了,或者也可以直接觸發 swipe 事件。
只找到了更早的 touch 庫(剛開始 iOS 開發的時候寫的),部分代碼:
var Touchable = function() {
function Touchable(target) {
var self = this;
function Touch(touch) {
this.x = touch.pageX;
this.y = touch.pageY;
}
EventEmitter.call(self);
self.el = El.from(target);
self.touches = {};
attach(self, self.el);
self.on({
touchstart: function(e) {
log("touchstart");
// log(e);
forEach(e.changedTouches, function(touch) {
capture(self, touch);
// log(touch);
});
},
touchmove: function(e) {
forEach(e.changedTouches, function(touch) {
var ot = self.touches[touch.identifier];
if (!ot)
return;
var t = new Touch(touch);
var dx = t.x - ot.x,
dy = t.y - ot.y;
if (ot.isSwipe === undefined && Math.abs(dy) > 10) {
ot.isSwipe = false;
ot.isScrolling = true;
self.emit("touchscrollstart", e);
} else if (ot.isSwipe === undefined && Math.abs(dy) < 10 && Math.abs(dx) > 30) {
e.preventDefault();
ot.isSwipe = true;
} else if (Math.abs(dy) > 30) {
ot.isSwipe = false;
}
});
},
touchend: function(e) {
log("touchend");
// log(e);
// log(self.touches);
forEach(e.changedTouches, function(touch) {
var ot = self.touches[touch.identifier];
if (!ot)
return;
var t = new Touch(touch);
log(ot);
log(t);
var dx = t.x - ot.x,
dy = t.y - ot.y;
if (Math.abs(dx) < 10 && Math.abs(dy) < 10)
self.emit("touchtap", e);
else if (ot.isSwipe)
self.emit("touchswipe", e);
else if (ot.isScrolling)
self.emit("touchscrollend", e);
uncapture(self, touch);
});
// log(self.touches);
},
touchcancel: function(e) {
log("touchcancel");
// log(e);
forEach(e.changedTouches, function(touch) {
uncapture(self, touch);
// log(touch);
});
}
});
function forEach(a, f) {
Array.prototype.forEach.call(a, f);
}
function capture(self, touch) {
var id = touch.identifier;
var t = new Touch(touch);
self.touches[id] = t;
}
function uncapture(self, touch) {
var id = touch.identifier;
delete self.touches[id];
}
}
Touchable.prototype = Object.create(EventEmitter.prototype, Obj.descriptor({
constructor: Touchable
}));
function attach(self, el) {
"touchstart touchmove touchend touchcancel".split(" ").forEach(function(x) {
self.el.on(x, function(e) {
self.emit(x, e);
});
});
}
function setPush(set, element) {
if (set.indexOf(element) === -1)
set.push(element);
}
return Touchable;
}();
舊代碼很爛,見諒。