纪录fastclick中一次手动触发click事宜失利

在昨天的一个挪动端项目中引入fastclick后手动触发click事宜失利,查看了文档也没有找到处理的要领,末了经由历程看fastclick源码才处理。
假如不想看中心这么多笔墨,能够直接翻到末了看结论。

复原变乱现场

想要完成的功能为点击div1的时刻手动触发input的click事宜。代码以下:

<style>
    <div>
        <div class="div1" @click="handleClick">
            input标签是隐蔽的,只能看到div1
        </div>
        <input type="file" style="display: none" res="input">
    </div>
</style>

<script>
    export default {
        methos: {
            handleClick() {
                this.$refs.input.click()
            }
        }
    }
</script>

在没有引入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上没写,算是不测收成。

    原文作者:caoxuejun
    原文地址: https://segmentfault.com/a/1190000009246194
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞