faskclick

PC网页上的大部分操作都是用鼠标的,即响应的是鼠标事件,包括mousedown、mouseup、mousemove和click事件。一次点击行为,事件的触发过程为:mousedown -> mouseup -> click 三步。

手机上没有鼠标,所以就用触摸事件去实现类似的功能。touch事件包含touchstart、touchmove、touchend,注意手机上并没有tap事件。手指触发触摸事件的过程为:touchstart -> touchmove -> touchend。

当我们手触碰屏幕时,要过300ms左右才会触发mousedown事件,所以click事件在手机上看起来就像慢半拍一样。 为什么这么设计呢? 因为它想看看你是不是要进行双击(double tap)操作。用过Zepto或KISSY等移动端js库的人肯定对tap事件不陌生,我们做PC页面时绑定click,相应地手机页面就绑定tap。但原生的touch事件本身是没有tap的,js库里提供的tap事件都是模拟出来的。

不应用 FastClick 的场景,如果 viewport meta 标签 中设置了 width=device-width, Android 上的 Chrome 32+ 会禁用 300ms 延时;

<meta name="viewport" content="width=device-width, initial-scale=1">

viewport meta 标签如果设置了 user-scalable=no,Android 上的 Chrome(所有版本)都会禁用 300ms 延迟。

测试延迟情况

XX.ontouchstart = function(){
        startTime =Date.now();
    };
XX.ontouchend = function(){
        pre.innerHTML += (‘ontouchend : ‘ + (Date.now() - startTime) + ‘\n‘);
    };
XX.onclick = function(){
        pre.innerHTML += (‘click : ‘ + (Date.now() - startTime));
    }
if (‘addEventListener‘ in document) {
    document.addEventListener(‘DOMContentLoaded‘, function() {
        FastClick.attach(document.body);
    }, false);
}

//优先兼容AMD方式
if (typeof define === ‘function‘ && typeof define.amd === ‘object‘ && define.amd) {
  define(function() {
    return FastClick;
  });
} else if (typeof module !== ‘undefined‘ && module.exports) {
  //兼容commonJs风格
  module.exports = FastClick.attach;
  module.exports.FastClick = FastClick;
} else {
  //最后兼容原生Js
  window.FastClick = FastClick;
} 

核心方法

//391-450:onTouchStart
FastClick.prototype.onTouchStart = function(event) {
  //tapDelay默认300毫秒,点击时间差小于300毫秒,则阻止事件再次触发,阻止短时间内双击的问题
  if ((event.timeStamp - this.lastClickTime) < this.tapDelay) {
    event.preventDefault();
  }
}
//521-610:onTouchEnd
if (!this.needsClick(targetElement)) {
  // 如果这不是一个需要使用原生click的元素,则屏蔽原生事件,避免触发两次click
  event.preventDefault();
  // 触发一次模拟的click
  this.sendClick(targetElement, event);
}
//294-309:sendClick(核心方法)
//这个事件会在onTouchEnd中用到,经过一系列的判断,符合条件,调用这个模拟事件
FastClick.prototype.sendClick = function(targetElement, event) {
  var clickEvent, touch;
  //创建一个鼠标事件
  clickEvent = document.createEvent(‘MouseEvents‘);
  //初始化鼠标事件
  clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
  //触发这个事件
  targetElement.dispatchEvent(clickEvent);
};

用Zepto的插件touch.js中tap事件,来解决移动浏览器中300毫秒延迟的问题。但是出现了各种击穿现象

  1. 同页面tap点击弹出弹层,弹层中也有一个button,正好重叠的时候,会出现击穿
  2. tap事件点击,页面跳转,新页面中同位置也有一个按钮,会出现击穿

我们可以看下Zepto对 singleTap 事件的处理。见源码 136-143 行,可以看出在 touchend 响应 250ms 无操作后,则触发singleTap。

//trigger single tap after 250ms of inactivity
else {
  touchTimeout = setTimeout(function(){
    touchTimeout = null
    if (touch.el) touch.el.trigger(‘singleTap‘)
    touch = {}
  }, 250)
}
  1. zepto中的 tap 通过兼听绑定在 document 上的 touch 事件来完成 tap 事件的模拟的,是通过事件冒泡实现的。在点击完成时(touchstart / touchend)的 tap 事件需要冒泡到 document 上才会触发。而在冒泡到 document 之前,手指接触和离开屏幕(touchstart / touchend)是会触发 click 事件的。
  2. 因为 click 事件有延迟(大概是300ms,为了实现safari的双击事件的设计),所以在执行完 tap 事件之后,弹出层立马就隐藏了,此时 click 事件还在延迟的 300ms 之中。当 300ms 到来的时候,click 到的其实是隐藏元素下方的元素。
  3. 如果正下方的元素有绑定 click 事件,此时便会触发,如果没有绑定 click 事件的话就当没发生。如果正下方的是 input 输入框(或是 select / radio / checkbox),点击默认 focus 而弹出输入键盘,也就出现了上面的“点透”现象。
时间: 2024-10-04 11:06:35

faskclick的相关文章

移动端开发:使用jQuery Mobile还是Zepto

原:http://blog.csdn.net/liubinwyzbt/article/details/51446771 jQuery Mobile和Zepto是移动端的js库.jQuery Mobile相当于PC端的jQuery UI,它提供了很多页面的UI库,能够很快的开发出漂亮的界面,适合公司没有UI设计师的前端开发人员来进行移动端的开发.Zepto相当于PC端的jQuery,它提供了很多方法和功能,能够很快的实现各种需求和功能,适合公司有UI设计师的前端开发人员来进行移动端的开发. jQu

JQUERY相关

https://github.com/mythz/jquip/ http://zeptojs.com/ http://devework.com/jquery-builder.html http://projects.jga.me/jquery-builder/ jquery瘦身 源码阅读 http://www.cnblogs.com/lovesueee/archive/2012/10/18/2730287.html https://www.zhihu.com/question/20521802

移动端JS库

今天整理下移动端的js库,然后闷头研究一种好了. 从别的地扒下来的,笔记. 1. jQuery Mobile jQuery Mobile快速开发出支持多种移动设备的Mobile应用用户界面.它是当前最流行的移动开发框架. jQuery Mobile给主流移动平台带来jQuery核心库,会发布一个完整统一的jQuery移动UI框架.用jQuery Mobile为移动设备(包括智能手机和平板电脑)开发网站应用程序,RSS阅读器等应用. 假如你不熟悉jQuery,可以选择 MooTools Mobil

那些眼花缭乱的前端框架

原文:http://www.w2bc.com/Article/32117 如果你的团队刚刚组建或者框架知识了解不深入,那么开发移动端,使用单一的库就行了. 比如:jQuery mobile或Zepto. 使用jQuery mobile可以省略很多UI设计或者说重构的一些工作,在公司团队中,如果没有这方面的成员时,可以使用此库.但是此库性能不好,兼容性一般,UI限制大,请慎重使用. 使用Zepto开发,性能上最好的,而兼容性比较好,跟jQuery有同样的API,只是需要自己设计UI,以及重构.to

移动端300ms兼容问题(移动端经典问题)

移动端300ms延迟原因 2007 年初.苹果公司在发布首款 iPhone 前夕,遇到一个问题:当时的网站都是为大屏幕设备所设计的.于是苹果的工程师们做了一些约定,应对 iPhone 这种小屏幕浏览桌面端站点的问题. 双击缩放(double tap to zoom),这也是会有上述 300 毫秒延迟的主要原因.双击缩放,即用手指在屏幕上快速点击两次,iOS 自带的 Safari 浏览器会将网页缩放至原始比例. 假定这么一个场景.用户在 iOS Safari 里边点击了一个链接.由于用户可以进行双

兼容和Error

兼容 IE兼容 ie没有forEach if(!Array.prototype.forEach) { Array.prototype.forEach = function(fun){ var len = this.length; if(typeof fun != "function"){ throw new TypeError(); } var thisp = arguments[1]; for(var i = 0; i < len; i++){ if (i in this){