Home >Web Front-end >JS Tutorial >Use native JS to encapsulate Tap events to solve the 300ms delay on the mobile terminal

Use native JS to encapsulate Tap events to solve the 300ms delay on the mobile terminal

高洛峰
高洛峰Original
2016-11-19 11:28:561865browse

FastClick

There is now a ready-made plug-in fastclick that can solve this problem, but it also has disadvantages:

The latest version of the plug-in on GitHub is 25.4kb in size. Lightweight is the trend, so save what you can.

Its core idea is to cancel the default click time, determine the type of the current DOM node, and perform corresponding operations. This judgment process is relatively cumbersome.

MyTapEvent

I have recently been working on a WeChat project. Due to certain drawbacks of the fastclick plug-in, I developed a simple tap event. The main ideas are as follows:

Thinking

A tap event includes touchstart and touchmove (slight movement) ) and the three states of touchend

The callback method is executed after touchend

According to the default judgment of the Chrome browser, the movement amount of the click is canceled. If the finger offset (horizontal or vertical) exceeds 15px, it is judged as scrolling and the tap event is canceled

If your finger is pressed for too long, it will not be regarded as a click. The default time interval is 500ms

Use HTMLElement to expand the prototype to easily add Events

Use singleton mode to ensure that it is only loaded once

ok, settle down and start writing the code It’s much clearer:

if (!HTMLElement.prototype.addTapEvent) {
    HTMLElement.prototype.addTapEvent = function(callback) {        var tapStartTime = 0,
            tapEndTime = 0,
            tapTime = 500, //tap等待时间,在此事件下松开可触发方法
            tapStartClientX = 0,
            tapStartClientY = 0,
            tapEndClientX = 0,
            tapEndClientY = 0,
            tapScollHeight = 15, //水平或垂直方向移动超过15px测判定为取消(根据chrome浏览器默认的判断取消点击的移动量)
            cancleClick = false;        this.addEventListener('touchstart', function() {
            tapStartTime = event.timeStamp;            var touch = event.changedTouches[0];
            tapStartClientX = touch.clientX;
            tapStartClientY = touch.clientY;
            cancleClick = false;
        })        this.addEventListener('touchmove', function() {            var touch = event.changedTouches[0];
            tapEndClientX = touch.clientX;
            tapEndClientY = touch.clientY;            if ((Math.abs(tapEndClientX - tapStartClientX) > tapScollHeight) || (Math.abs(tapEndClientY - tapStartClientY) > tapScollHeight)) {
                cancleClick = true;
            }
        })        this.addEventListener('touchend', function() {
            tapEndTime = event.timeStamp;            if (!cancleClick && (tapEndTime - tapStartTime) <= tapTime) {
                callback();
            }
        })
    }
}

Usage

HTMLElement.addTapEvent(function(){    //do something...})
如:document.querySelect(&#39;#test&#39;).addTapEvent(function(){
    alert(&#39;this is a tap event&#39;);
})

Case

Here is a mobile case, which also includes the knowledge of closures. The first 20 items are tap events, and the last 30 items are click events. You can use it on your mobile phone Try the effect and feel the difference between the two methods:

<style media="screen">
    li {        padding: 20px;
    }</style><!DOCTYPE html><html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <meta name="apple-touch-fullscreen" content="yes">
        <meta name="apple-mobile-web-app-status-bar-style" content="black">
        <meta name="format-detection" content="telephone=no,email=no">
        <meta name="x5-orientation" content="portrait">
        <title>test</title>
    </head>
    <body>
        <ul></ul>
    </body>
    <script type="text/javascript">
        if (!HTMLElement.prototype.addTapEvent) {
            HTMLElement.prototype.addTapEvent = function(callback) {                var tapStartTime = 0,
                    tapEndTime = 0,
                    tapTime = 500, //tap等待时间,在此事件下松开可触发方法
                    tapStartClientX = 0,
                    tapStartClientY = 0,
                    tapEndClientX = 0,
                    tapEndClientY = 0,
                    tapScollHeight = 15, //水平或垂直方向移动超过15px测判定为取消(根据chrome浏览器默认的判断取消点击的移动量)
                    cancleClick = false;                this.addEventListener(&#39;touchstart&#39;, function() {
                    tapStartTime = event.timeStamp;                    var touch = event.changedTouches[0];
                    tapStartClientX = touch.clientX;
                    tapStartClientY = touch.clientY;
                    cancleClick = false;
                })                this.addEventListener(&#39;touchmove&#39;, function() {                    var touch = event.changedTouches[0];
                    tapEndClientX = touch.clientX;
                    tapEndClientY = touch.clientY;                    if ((Math.abs(tapEndClientX - tapStartClientX) > tapScollHeight) || (Math.abs(tapEndClientY - tapStartClientY) > tapScollHeight)) {
                        cancleClick = true;
                    }
                })                this.addEventListener(&#39;touchend&#39;, function() {
                    tapEndTime = event.timeStamp;                    if (!cancleClick && (tapEndTime - tapStartTime) <= tapTime) {
                        callback();
                    }
                })
            }
        }        var ul = document.querySelector(&#39;ul&#39;);        for (var i = 1; i <= 20; i++) {            var li = document.createElement(&#39;li&#39;);
            li.innerHTML = i;
            li.addTapEvent(function() {                var x = i;                return function() {
                    alert(x);
                }
            }())
            ul.appendChild(li);
        }        for (var j = 21; j <= 50; j++) {            var li = document.createElement(&#39;li&#39;);
            li.innerHTML = j;
            li.onclick = function() {                var x = j;                return function() {
                    alert(x);
                }
            }()
            ul.appendChild(li);
        }    </script></html>


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn