A single click or click is the act of pressing a computer mouse button
once without moving the mouse.
So, mouseup/touchend itself doesn't mean click. You have to check whether it's moved or not.
And as the touch screen is not as accurate as mouse, a move less than 10px shoud be treated as still.
But in this case the wrong handler is not the only reason causes the bug. Safari Mobile will send the same event twice, if there is a alert in the handler.
So, record what you received, ignore redundant events. Or, do NOT use alert.
var SingleTouch = function(el, onclick) {
var id = -1, self = this;
var y = false;
self.onclick = typeof onclick === "function" ? onclick : function() {};
el.addEventListener("touchstart", function(e) {
var touch;
if (touch = getNewTouch(e.changedTouches)) {
if (id !== -1)
log("touchignore " + id);
id = touch.identifier;
log("touchdown " + id);
y = touch.pageY;
}
});
el.addEventListener("touchend", function(e) {
var touch;
if (id !== -1 && (touch = getTouch(e.changedTouches))) {
log("touchup " + id);
var dy = Math.abs(touch.pageY - y);
if (dy < 10) {
log("touchclick " + dy);
self.onclick(e);
} else {
log("touchscroll " + dy)
}
y = false;
id = -1;
}
});
el.addEventListener("touchcancel", function(e) {
if (getTouch(e.changedTouches)) {
log("touchcancel " + id);
id = -1;
y = false;
}
});
function getTouch(touches) {
var touch;
return Array.prototype.some.call(touches, function(x) { return x.identifier === id && (touch = x) }) && touch;
}
function getNewTouch(touches) {
var touch;
return Array.prototype.some.call(touches, function(x) { return x.identifier !== id && (touch = x) }) && touch;
}
function log() {}
};
new SingleTouch(ul).onclick = function(e) {
alert(e.target.textContent);
};
"touchend" is not "click".
So, mouseup/touchend itself doesn't mean click. You have to check whether it's moved or not.
And as the touch screen is not as accurate as mouse, a move less than 10px shoud be treated as still.
But in this case the wrong handler is not the only reason causes the bug. Safari Mobile will send the same event twice, if there is a
alert
in the handler.So, record what you received, ignore redundant events. Or, do NOT use
alert
.可以试试延迟半秒执行函数的方法(没试过,不保证一定可以使用)
touchend作为click的替代很不严禁。例如你滑动网页时,恰好划到绑定touchend的dom上,touchend会被触发,这显然不是用户期望的,另外如果你click和touch混用,会造成点击穿透。 github上有个fastclick的项目,你可以看下。当然也可以自己通过touchstart和touchmove 和touchend模拟tap事件,提高自己对touch的理解。
用这个吧,取消click的300毫秒延迟,https://github.com/ftlabs/fastclick