欢迎关注富途web开发团队 ,缺人从众css
有一次给公司作了个自适应的的费用介绍页,主要是关于收费标准的调整,老板表示很重视,适用人群也不少,因此也反馈获得几个不常遇到的问题,其中一个就是关于touchstart
与click
事件的问题。这里记录一下,欢迎指正。前端
某天中午,开发了好几天的费用介绍页终于上线了。运营同窗满怀信心地发送了收费标准页面的推广消息,而后咱们都潇洒地吃午餐去了。正吃着午餐的时候,收到微信群中某客户的反馈:咱们的页面最关键的地方——收费详情点击没有反应!android
随后咱们查看了前端错误上报和日志,没有任何线索。与客户确认环境,客户使用的是 windows PC 。web
但奇怪的是,我测试了多台设备,仍然没法重现问题。在同事的机器上也没能复现这个问题。windows
咱们从新审视了一遍事件绑定的代码,发现其实很是简单。bash
var tap = 'ontouchstart' in window ? 'touchstart' : 'click';
wrap.addEvenListener(tap, function(){
signUp();
});
复制代码
惟一有点特殊的就是咱们的页面是自适应的,为了不移动端点击 300ms 延迟,在绑定前作了一下判断,移动端绑定了touchstart
事件,PC 端绑定了click
事件。然而这段代码看起来也是人畜无害,并不至于致使点击没有反应。微信
咱们再次询问了客户更详细的环境信息,得到了一个很是关键的信息,客户使用的是联想的笔记本。因为在 surface 出来的时候组里有同事关注过,想起来当时联想也出了不少触屏笔记本。因而和客户再次联系,确认了他使用的就是联想的触屏笔记本。iphone
至此问题就很是明确了,问题最终仍是定位在绑定的“点击”事件上。咱们在检测时只是粗暴地检测了设备是否支持触控事件,却忽略了支持触控事件的仍然多是 PC 设备,客户仍然可能经过点击鼠标来进行操做。这实际上反映出咱们忽略了用户设备的多样性,开发的时候对用户设备作了太多的假设,最终致使咱们觉得它是一台手机,结果它是一台货真价实的笔记本电脑。函数
概括起来,关键的点就是:测试
touchstart
和click
事件;touchstart
事件,默认必然会致使触发click
事件,可是触发click
事件,不必定会致使touchstart
事件被触发;touchstart
事件,可是鼠标操做只能触发click
,致使touchstart
不触发;至此,问题的缘由已经分析完毕,如何应对又成了一个问题。这个问题的关键在于肯定不一样设备上使用“点击”事件的策略。大体分为以下几种:
function isMobile() {
return navigator.userAgent.match(/(blackberry|configuration\/cldc|hp |hp-|htc |htc_|htc-|iemobile|kindle|midp|mmp|motorola|mobile|nokia|opera mini|opera |Googlebot-Mobile|YahooSeeker\/M1A1-R2D2|android|iphone|ipod|mobi|palm|palmos|pocket|portalmmm|ppc;|smartphone|sonyericsson|sqh|spv|symbian|treo|up.browser|up.link|vodafone|windows ce|xda |xda_)/i) ? true : false;
}
var tap = isMobile() ? 'touchstart' : 'click';
复制代码
//引入FastClick
var FastClick = require('tool-fastclick');
//页面初始化时调用
new FastClick(document.body);
复制代码
注:
tool-fastclick
是组内 fork 的 FastClick 版本,目前没有开源。咱们对其中存在的问题进行了一部分修复,好比:同个页面有多个 select 框选择时,会跳选项的 bug 。
其实最好的方案是不要在绑定的时候进行判断,而是对touchstart
和click
同时绑定,可是在touchstart
触发的时候暂时取消后续 click 的响应。
具体的实施方式有三种:
touchstart
事件响应中调用preventDefault()
方法,阻止后续click
事件的触发touchstart
事件中设置一些标记,或者取消click
事件的绑定,使得click
事件触发时不会触发咱们绑定的逻辑,在一段时间(例如300-500ms)后再恢复固然,和上面同样,每种方案都有利弊。
方案1取消了后续click
事件的触发,在多个事件绑定叠加或者多人合做的时候,有可能致使一些依赖click
事件的逻辑出现bug。
方案2和方案3的原理基本同样,实施起来有必定的复杂度,并且本质上属于 hack 的方案,应对一些很是规场景时就不适用了。好比须要快速连续点击的场景,或者用户点击很是慢的场景等等。
总之,没有万全之策,呵呵……
有人可能会对文章最前提到的收费介绍页比较感兴趣,来了,看这里。