博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
记录fastclick中一次手动触发click事件失败
阅读量:7125 次
发布时间:2019-06-28

本文共 2125 字,大约阅读时间需要 7 分钟。

在昨天的一个移动端项目中引入fastclick后手动触发click事件失败,查看了文档也没有找到解决的办法,最后通过看fastclick源码才解决。

如果不想看中间这么多文字,可以直接翻到最后看结论。

还原事故现场

想要实现的功能为点击div1的时候手动触发input的click事件。代码如下:

在没有引入fastclick的时候,可以按照预期工作,引入之后,在Android中也可以正常工作,但是在iOS却无论如何也不行。即使在input标签加上needsclick类也不行。

神奇的是如果连续手动触发两次click事件,则在iOS中就可以正常工作了!!

代码如下:

handleClick() {    this.$refs.input.click()    this.$refs.input.click()}

想来想去,原因只能出在fastclick身上,首先看了文档,并没有发现解决的方法,只能去看源码了。虽然第一次用fastclick的时候就读过代码,当时只不过为了知道大概实现原理泛泛的读了一遍,不够细致。这次又重新看了一遍。关于源码的解读网上有很多,这里就不细说,代码不长,建议最好自己读一读。

追踪溯源,找到问题原因症结

看完源码,就可以回答之前的疑问了。

1、为什么安卓可以正常工作?

if (deviceIsAndroid) {    metaViewport = document.querySelector('meta[name=viewport]');    if (metaViewport) {        // Chrome on Android with user-scalable="no" doesn't need FastClick (issue #89)        if (metaViewport.content.indexOf('user-scalable=no') !== -1) {            return true;        }        // Chrome 32 and above with width=device-width or less don't need FastClick        if (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) {            return true;        }    }// Chrome desktop doesn't need FastClick (issue #15)} else {    return true;}

在fastclick刚运行的时候,就判断是否需要使用fastclick,我的安卓测试机chrome大于32 且设置了width=device-width。所以在安卓下我点击使用的原生click事件当然没问题。

2、为什么iOS需要手动触发两次click事件才可以?

这就是这次“事故”的关键所在,当我点击的时候,一共触发了单词click事件,其中第一次为点击div触发,后两次为手动触发input的click事件。

第一次click事件时,fastclick在onTouchStart中将targetElement设置为div1,

这次成功执行sendClick() ,目标并不是我们想要的input。

紧接着是第一次手动触发click事件,但是因为是通过element.click()函数手动触发,所以没有onTouchStart这个过程,因此此时targetElement当然还是div1 !!! 这时needsClick返回了false,从而导致onClick中onMouse函数也返回了false,并终止了事件,随后就将targetElement置为null。

在第二次手动click事件中,因为此时targetElement为null,所以在onMouse中返回true,接着从而顺利触发了原生click事件。

if (!this.targetElement) {    return true;}
3、为什么在input标签加上needsclick也不能成功触发click事件?

因为第一次手动执行click() 的时,这时候的targetElement还是div1,即点击时的元素,而我将needsclick绑定在input上了,因此当然在targetElement上找不到needsclick了。

此时我们也就找到了解决问题的办法:将needsclick绑定在div1,即实际点击的元素上。

结论及收获

  • 如果想触发原生click事件,请将needsclick绑定在实际点击的元素上,即e.targe上,而不是你手动触发的元素上。这可以说是fastclick的一个小bug,因为之前的点击影响了后面的点击。

  • 只能在click的回调函数中手动触发element.click() ,否则无效,有兴趣的可以试试。这个在MDN上没写,算是意外收获。

转载地址:http://eveel.baihongyu.com/

你可能感兴趣的文章
puppet自动化运维
查看>>
linux系统配置基础--此篇会不断的完善
查看>>
git命令记录
查看>>
jenkins 配置
查看>>
关于dubbo服务的xml配置文件报错的问题
查看>>
Linux 环境变量和alias设置
查看>>
Spring MVC +Hibernate集成
查看>>
搭建LAMP环境,并实践基于DNS做基于域名的虚拟主机
查看>>
neutron-metadata-proxy无响应,导致windos2003密码透传失败
查看>>
用Python实现用户登录接口
查看>>
毕业前1个月的想法
查看>>
例程详析动态链接库
查看>>
geopy使用详解
查看>>
Notebook Workflows: The Easiest Way to Implement Apache Spark Pipelines
查看>>
mysql必知必会表样例
查看>>
我的友情链接
查看>>
python logging 模块在windows报错ConfigParser.NoSectionError: No section
查看>>
windows下python3虚拟环境搭建
查看>>
error at ::0 formal unbound in pointcut
查看>>
关于linux下Squid透明代理的试验
查看>>