移动端使用fastclick时,模拟原生浏览器对象

移动浏览器原生click事件有300ms的延时,这是浏览器为了区分究竟是双击仍是单击事件。
(实际上有些移动浏览器不支持双击事件。PC版chrome在手机模式下,当禁止用户双击缩放页面时(即有viewport meta标签时,无论user-scalable为yes或no),双击会触发两次click事件,但并不会触发dblclick事件,当容许用户双击缩放页面时(即没有viewport meta标签时),双击不会触发click事件,也不会触发dblclick事件,而是会缩放页面;在正常模式下(即PC模式),双击会先触发两次click事件,而后再触发一次dblclick事件)

fastclick解决了单击事件的300ms延迟问题,原理大体以下:
touchstart,touchmove,touchend事件是没有延迟的,当touchend事件触发时,若是从touchstart触发到touchend触发的过程当中没有移动且时间间隔没有超过界限,那么就执行event.prentDefault()且人为的在目标元素上派发Click事件(targetElement.dispatchEvent(clickEvent),dispatchEvent派发的事件就跟咱们在浏览器中实际操做触发的事件同样,可以传播,即有捕获阶段和冒泡阶段)。因为执行了event.prentDefault(),因此会致使浏览器原生的单击和双击事件不会再触发了。

经过上面的讲解,咱们能够知道,使用fastclick后,是没法区分单击和双击的,fastclick通通都认为是单击事件,因此咱们只能人为地来模拟单击事件和双击事件(300ms内只有一次点击为单击事件,不然就是双击或者多击事件)。chrome

//给$elem元素自定义click事件
function customClick($elem) {
var lastTouch, //上一次touchstart触发的时间
touching, //是否正在触屏
moved, //是否touchmove过
multiClick, //是否单指多击
multiFinger; //是否多指操做浏览器

function onTouchStart(event) {
var t = 300,
time = new Date().getTime();spa

if (event.touches.length !== 1) { //多指操做
multiFinger = true;
} else {
if (lastTouch && time - lastTouch < t) {
//!multiClick && $elem.dblclick(); 双击事件
multiClick = true;
} else {
multiClick = false;
moved = false;
multiFinger = false;
setTimeout(function () {
//没有多指操做过,没有屡次点击过,触屏期间没有touchmove过,且如今没有触屏
!multiFinger && !touching && !multiClick && !moved && $elem.clicked();
}, t);
}
}scala

lastTouch = time;
touching = true;
}事件

function onTouchEnd(event) {
!event.touches.length && (touching = false);
}get

function onTouchMove(event) {
moved = true;
}io

$elem.on('touchstart', onTouchStart).on('touchend', onTouchEnd).on('touchmove', onTouchMove);
}event

相关文章
相关标签/搜索