移动端点击那些事

简介

这篇文章主要是一些总结的移动端开发的一些坑,以及爬坑方法。

正文

ios-webview点击事件(click)延迟

在pc端开发时常用的点击事件中使用最对的可能是click,但是在移动端的网页中,默认是拥有双击缩放这个功能的,那么为了使这个功能生效,页面通常是在第一次点击完之后先不触发click事件,而是等待300ms之后看是否有第二次点击,有的话就缩放,没有就触发点击事件,这就造成了300ms延迟。
幸运的是谷歌浏览器将在包含 width=device-width 或者置为比 viewport 值更小的页面上禁用双击缩放。当然,没有双击缩放就没有 300 毫秒点击延迟。随后各大浏览器也相应支持,也包括ios的safari。但是兼容性不是很好,例如ios的webview仍然有300ms的延迟,原因未知,等我研究完ios开发再来回答。

解决方法:

touchTap

但此时又会出现一个新的问题,tap事件穿透。

tap事件的原理是监听body上的touchstart,touchmove以及touchend来进行判断,那么正常情况下tap事件还没有冒泡到body时,click事件就触发了。但是当页面有300ms延迟是,就会造成事件穿透。当然解决有两个办法,最简单也是副作用最大的办法是将页面所有click事件全部切换成touchTap事件,第二个就是使用fastclick。

fastclick

打开fastclick源码可以看到有一个sendClick方法。

/**
     * Send a click event to the specified element.
     *
     * @param {EventTarget|Element} targetElement
     * @param {Event} event
     */
    FastClick.prototype.sendClick = function(targetElement, event) {
        var clickEvent, touch;

        // On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)
        if (document.activeElement && document.activeElement !== targetElement) {
            document.activeElement.blur();
        }

        touch = event.changedTouches[0];

        // Synthesise a click event, with an extra attribute so it can be tracked
        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);
        clickEvent.forwardedTouchEvent = true;
        targetElement.dispatchEvent(clickEvent);
    };

可以看出这里是用document的createEventAPI模拟了一次点击事件。紧接着我们在FastClick.prototype.onTouchEnd这个方法下面发现这里调用了this.sendClick方法,由此可以看出fastclick的原理就是在touchEnd事件中增加判断,看是否是一次移动端的点击事件,如果是,就主动出发click,这样既解决了移动端300ms延迟,又解决了事件穿透,是一个比较好的解决方案。

你可能感兴趣的:(移动端点击那些事)