zoukankan      html  css  js  c++  java
  • web移动端_移动端的左右手势以及tap事件(解决移动端点击时出现的300ms毫秒延时问题)

    一、前言                                                                               

    本文主要涉及:

                          1、移动端的touch事件

                          2、移动端的滑动手势实现的原理

                          3、移动端点击的时候出现的300ms延时问题

     

    二、主要内容                                                                        

    1、移动端的touch事件

        (1)常见的touch事件

         touch事件是移动端的触摸事件  并且是一组事件。

         touchstart          当手指触摸到屏幕的时候会触发

         touchmove        当手指在屏幕上来回滑动的时候会触发

         touchend           当手指离开屏幕的时候会触发

         touchcancel       当被迫终止滑动的时候触发

        (2)分析常用的事件对象

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <title>Title</title>
        <style>
            body{
                margin: 0;
                padding: 0;
            }
            .box{
                width: 200px;
                height: 200px;
                background: pink;
                float: left;
            }
        </style>
    </head>
    <body>
    
    <div class="box"></div>
    <script>
        window.onload = function () {
            var box = document.querySelector('.box');
            box.addEventListener('touchstart',function (e) {
                console.log('start');
                console.log(e);  //打印出触摸开始的事件对象
             
            });
            box.addEventListener('touchmove',function (e) {
                console.log('move');
                console.log(e);//打印出触摸过程中的事件对象
            });
            box.addEventListener('touchend',function (e) {
                console.log('end');
                console.log(e);//打印出触摸结束的事件对象
            });
            /*box.addEventListener('click',function (e) {
                console.log('click');
                console.log(e);
            });*/
        }
    </script>
    </body>
    </html>

    start:

    move:

     

    end

     

    (3)触摸事件涉及到的事件对象

    TouchList 触摸点(一个手指触摸就是一个触发点,和屏幕的接触点的个数)的集合
    changedTouches 改变后的触摸点集合
    targetTouches 当前元素的触发点集合
    touches 页面上所有触发点集合

    2、移动端的滑动手势实现的原理

      (1)分析:滑动实现的原理就是让触摸的元素随着手指的滑动做位置的改变。置的改变需要当前手指的坐标。每个触摸点中会记录当前触摸点的坐标 e.touches[0]

      (2)移动端的手势事件具体实现

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <title>Title</title>
        <style>
            body {
                margin: 0;
                padding: 0;
            }
    
            .box {
                width: 200px;
                height: 200px;
                background: pink;
                float: left;
            }
        </style>
    </head>
    <body>
    <div class="box"></div>
    <script>
        window.onload = function () {
            /*1. 理解移动端的手势事件*/
            /*2. swipe swipeLeft  swipeRight swipeUp swipeDown */
            /*3. 左滑和右滑手势怎么实现*/
            var bindSwipeEvent = function (dom,leftCallback,rightCallback) {
                /*手势的条件*/
                /*1.必须滑动过*/
                /*2.滑动的距离50px*/
                var isMove = false;
                var startX = 0;
                var distanceX = 0;
                dom.addEventListener('touchstart',function (e) {
                    startX = e.touches[0].clientX;
                });
                dom.addEventListener('touchmove',function (e) {
                    isMove = true;
                    var moveX = e.touches[0].clientX;
                    distanceX = moveX - startX;
                });
                dom.addEventListener('touchend',function (e) {
                    /*滑动结束*/
                    if(isMove && Math.abs(distanceX) > 50){
                        if(distanceX > 0){
                            rightCallback && rightCallback.call(this,e);
                        }else{
                            leftCallback && leftCallback.call(this,e);
                        }
                    }
                    /*重置参数*/
                    isMove = false;
                    startX = 0;
                    distanceX = 0;
                });
            }
            bindSwipeEvent(document.querySelector('.box'),function (e) {
                console.log(this);
                console.log(e);
                console.log('左滑手势');
            },function (e) {
                console.log(this);
                console.log(e);
                console.log('右滑手势');
            });
    
        }
    </script>
    </body>
    </html>

    3、移动端点击的时候出现的300ms延时问题

    (1)出现的原因:移动端的tap事件 轻触 轻击响应时间快。但是在移动端也有滑动事件,为了区别手指在移动端是滑动事件还是点击事件。当点击后会有300ms延时来区分到底用户要做的是滑动事件还是点击事件。这样会影响用户体验。

    (2)解决方案

    方案一:使用tap事件(不是移动端原生事件,通过touch相关事件衍生过来)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <title>Title</title>
        <style>
            body {
                margin: 0;
                padding: 0;
            }
    
            .box {
                width: 200px;
                height: 200px;
                background: pink;
                float: left;
            }
        </style>
    </head>
    <body>
    <div class="box"></div>
    
    <script>
        window.onload = function () {
            /*使用tap事件*/
            /*1. 响应的速度比click要快   150ms */
            /*2. 不能滑动*/
            var bindTapEvent = function (dom, callback) {
                /*事件的执行顺序*/
                /*在谷歌浏览器模拟看不到300ms的效果*/
                /*在真机上面才能看看到延时效果*/
                var startTime = 0;
                var isMove = false;
                dom.addEventListener('touchstart', function () {
                 
                    startTime = Date.now();//获取到手指刚放下去的事件
                  
                });
                dom.addEventListener('touchmove', function () {
                    //console.log('touchmove');
                    isMove = true;   //滑动的时候置为true
                });
                dom.addEventListener('touchend', function (e) {
                    //console.log('touchend');
                    console.log((Date.now() - startTime));
                    //当滑动的时间小于150ms, 并且isMove=false的时候,为点击
                    if ((Date.now() - startTime) < 150 && !isMove) {
                        callback && callback.call(this, e);
                    }
    
                    startTime = 0;
                    isMove = false;
                });
                /*dom.addEventListener('click',function () {
                 //console.log('click');
                 });*/
            }
    
            bindTapEvent(document.querySelector('.box'), function (e) {
                console.log(this);
                console.log(e);
                console.log('tap事件')
            });
        }
    </script>
    </body>
    </html>

    方案二:使用插件fastclick.min.js

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <title>Title</title>
        <style>
            body {
                margin: 0;
                padding: 0;
            }
    
            .box {
                width: 200px;
                height: 200px;
                background: pink;
                float: left;
            }
        </style>
    </head>
    <body>
    <div class="box"></div>
    <!--
    1. tap事件  轻击 轻触  (响应速度快)
    2. 移动端也有click事件 (在移动为了区分是滑动还是点击,click点击延时300ms)
    3. 影响用户体验 响应太慢了。
    4. 解决方案:
    4.1 使用tap事件(不是移动端原生事件,通过touch相关事件衍生过来) (zepto.js tap事件)了解其原理
    4.2 使用一个叫:fastclick.js 提供移动端click响应速度的
    4.2.1 下载:https://cdn.bootcss.com/fastclick/1.0.6/fastclick.min.js
    4.2.2 使用:
    -->
    <script src="../js/fastclick.min.js"></script>
    <script>
        /*当页面的dom元素加载完成*/
        document.addEventListener('DOMContentLoaded', function() {
            /*初始化方法*/
            FastClick.attach(document.body);
        }, false);
        /*正常使用click事件就可以了*/
    </script>
    </body>
    </html>

     4、移动端滑动事件与pc端滑动事件的兼容问题

     if(document.body.ontouchstart !== undefined){
                   canvas.ontouchstart = function(e){
                       var x = e.touches[0].clientX;
                    var y = e.touches[0].clientY;
    
                  if(isUseEarser){
                      
                      console.log(1111)
                      painting = true
                    context.clearRect(x,y,30,30)
                  }else{
                         painting = true
                      
                       lastPoint.x = x;
                       lastPoint.y = y;
                      
                  }
                  
                   }
    
                   canvas.ontouchmove = function(e){
                       var x = e.touches[0].clientX;
                    var y = e.touches[0].clientY;
                    console.log(isUseEarser)
                    if(isUseEarser){
                        context.clearRect(x,y,30,30)
                    }else{
                        if(painting){
                    
                        var newPoint = {"x":x, "y":y}
                        drawCircle(x,y,1)
    
                        drawLine(lastPoint.x,lastPoint.y,newPoint.x, newPoint.y)
                        lastPoint = newPoint
                    
                    }
    
                    }
    
                   }
    
                   canvas.ontouchend = function(e){
                       painting = false
    
                   }
    
           }else{
                   //鼠标按下去的时候画一个点
                canvas.onmousedown = function(e){
                    var x = e.clientX;
                    var y = e.clientY;
    
                  if(isUseEarser){
                      
                      console.log(1111)
                      painting = true
                    context.clearRect(x,y,30,30)
                  }else{
                         painting = true
                      
                       lastPoint.x = x;
                       lastPoint.y = y;
                      
                  }
                   
                }
    
    
                //鼠标移动的 时候画点
                canvas.onmousemove = function(e){
                    //移动的时候也要看是否有橡皮檫,如果有橡皮檫就檫,没有橡皮檫就画
                    var x = e.clientX
                    var y = e.clientY
                    console.log(isUseEarser)
                    if(isUseEarser){
                        context.clearRect(x,y,30,30)
                    }else{
                        if(painting){
                    
                        var newPoint = {"x":x, "y":y}
                        drawCircle(x,y,1)
    
                        drawLine(lastPoint.x,lastPoint.y,newPoint.x, newPoint.y)
                        lastPoint = newPoint
                    
                    }
    
                    }
                    
                }
    
                //鼠标拿起的时候
                canvas.onmouseup = function(){
                    painting = false
                }
               }
    
           }
            
    移动端与pc端兼容

    三、总结                                                                               

  • 相关阅读:
    垂直水平居中几种实现风格
    重绘(repaint)和回流(reflow)
    对象深拷贝
    PhantomJS not found on PATH
    d3.js 数据操作
    canvas 绘制圆弧
    d3.js 柱状图
    d3.js -- 比例尺 scales scaleLinear scaleBand scaleOrdinal scaleTime scaleQuantize
    d3.js -- select、selectAll
    map映射
  • 原文地址:https://www.cnblogs.com/xxm980617/p/11207355.html
Copyright © 2011-2022 走看看