移动端 事件

touch事件

什么是touch事件?
随着智能手机和平板电脑的普及, 越来越多的人用移动设备浏览网页,我们平时在pc浏览器上用的鼠标事件,比如:click, mouseover等, 已经无法满足移动设备触摸屏的特点。
触摸时代的到来,离不开触摸事件 touch事件用于移动端,可响应用户手指(或触控笔)对屏幕或者触控板操作,给基于触控操作,给基于触控的用户界面提供可靠的支持。

手机中click事件有300ms的延迟

移动端有个两次连续“轻触”是“放大”的操作,在你第一次被“轻触”后,浏览器需要先等一段时间,若有“连续的第二次轻触”,则进行“放大”操作,否则就执行click事件,这就导致了移动端所谓的300ms
click延迟,

JavaScript dblclick 事件失效

连续快速双击元素对象时会触发此事件。
移动端由于双击缩放的存在,pc端的dblclick事件也失效了。

移动端特有的touch事件

移动端浏览器都引入了触摸(touch)事件。

最基本4个事件:

  • touchstart: 当在屏幕上按下手指时触发
  • touchmove: 当在屏幕上移动手指时触发
  • touchend: 当手指从屏幕上离开的时候触发。
  • touchcancel 当系统停止跟踪触摸的时候触发。

touchcancel : 如电话接入或者弹出信息,会取消当前的touch操作,即触发touchcancel。一般会在touchcancel时暂停游戏、存档等操作。

preventDefault()事件可以阻止滚动。

如果你使用了触摸事件,可以调用 event.preventDefault()来阻止鼠标事件被触发。

touch相关的事件跟普通的其他dom事件一样使用,可以直接用addEventListener 向指定元素添加事件。

touchstart事件

​ 当用户手指触摸到的触摸屏的时候触发。

<div>
    点击我!
</div>
<script>
    var box = document.querySelector("div");
    box.addEventListener("touchstart", function (e) {
       console.log('touchstart'); 
    });
</script>

touchmove事件

当用户在触摸屏上移动触点(手指)的时候,触发这个事件。一定是先要触发touchstart事件,再有可能触发 touchmove 事件。

注意: 即使手指移出了 原来的target 元素,则 touchmove 仍然会被一直触发,而且 target 仍然是原来的 target 元素。

 <div>
   点击我!
 </div>
 <script>
     var box = document.querySelector("div");
     box.addEventListener("touchmove", function (e) {
        console.log('touchmove'); 
     });
 </script>

touchend事件

​当用户的手指抬起的时候,会触发 touchend 事件。如何用户的手指从触屏设备的边缘移出了触屏设备,也会触发 touchend 事件。

 <div>
   点击我!
 </div>
 <script>
     var box = document.querySelector("div");
     box.addEventListener("touchend", function (e) {
        console.log('touchend'); 
     });
 </script>

touchcancel事件

​当触点由于某些原因被中断时触发。

几种可能的原因:

  • 由于某个事件取消了触摸:例如触摸过程被一个电话打断。
  • 触点离开了文档窗口,而进入了浏览器的界面元素、插件或者其他外部内容区域。
  • 当用户产生的触点个数超过了设备支持的个数,从而导致 TouchList 中最早的 Touch对象被取消。

touchcancel 事件一般用于保存现场数据。比如:正在玩游戏,如果发生了 。
touchcancel事件,则应该把游戏当前状态相关的一些数据保存起来。

触摸事件对象?

TouchEvent :是描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件。这类事件用于描述一个或多个触点,使开发者可以检测触点的移动,触点的增加和减少,等等。

每个Touch 对象代表一个触点; 每个触点都由其位置,大小,形状,压力大小,和目标 组成。

TouchList 详解

TouchList 对象代表多个触点的一个列表。

​举例来讲, 如果一个用户用三根手指接触屏幕, 与之相关的TouchList 对每根手指都会生成一个Touch对象, 共计 3 个(touches 、targetTouches、changedTouches)。

touches

一个TouchList对象,包含当前所有屏幕上的触点的Touch对象,该属性不一定是当前元素的touchstart事件触发。(单触点)

targetTouches

也是一个TouchList对象,包含从当前元素touchstart事件触发的触点Touch对象。(多触点)

changedTouches

一个TouchList对象,对于touchstart事件, 这个TouchList对象列出在此次事件中包含屏幕上新增的触点(多触点)

touches和targetTouches只存储接触屏幕的触点,touchend时,touches和targetTouches是个空数组,所以要获取触点最后离开的状态要使用changedTouches。

操作:

放1个手指在div上
在这里插入图片描述
先放1个手指在其他地方,然后再放1个手指在div上

在这里插入图片描述
先放1个手指在其他地方,然后再逐渐放2个手指在div上
在这里插入图片描述

每个Touch对象包含的属性:

clientX:触摸目标在视口中的x坐标。(不计算滚动条)
clientY:触摸目标在视口中的y坐标。
identifier:标识触摸的唯一ID。
pageX:触摸目标在页面中的x坐标。(包含滚动条)
pageY:触摸目标在页面中的y坐标。
screenX:触摸目标在屏幕中的x坐标。
screenY:触摸目标在屏幕中的y坐标。
target:触目的DOM节点目标。

tap事件的封装:

点击事件的封装:
  • 移动端的点击事件会有300ms的延迟需要优化。
  • 触屏开始时间和结束的时间差要小于150ms
  • 触发点击事件是:先触发了touch事件,点击事件没有touchmove事件。
/*
* 参数说明
* el:绑定点击事件的对象
* callback: 点击事件触发后 要执行的代码
 */

//避免命名冲突
var myTouch = {
    //点击事件:首先有 touchstart 事件,不能移动 touchmove,touchend结束与touchstar开始时间差,小于150ms。
    tap: function (el, callback) {
        var isMove = false; //是否执行了touchmove事件
        var startTime = 0; //重置记录按下时的当前时间,默认为 0;
        // 传的 el 必须是对象
        if (typeof el === "object") {
            el.addEventListener("touchstart", function () {
                //按下时记录当前时间戳
                startTime = new Date() * 1;
            });
            el.addEventListener("touchmove", function () {
                isMove = true;
            });
            el.addEventListener("touchend", function (ev) {
                //触点离开屏幕时当前的时间
                var endTime = new Date() * 1;
                //触点抬起时判断是否是点击的事件。
                //结束时间 与 开始时间小于150ms;并且没有移动事件时为点击事件。
                if((endTime - startTime) < 150 && !isMove){
                    //执行回调函数
                    //callback 是否有值 && 执行函数
                    callback && callback(ev,el);
                }
                //记录的变量恢复初始值
                startTime = 0;
                isMove = false;
            })
        }
    }
}

swipe的封装

/**
     * @param {object} el:添加事件的DOM元素
     * @param {function} callback:单击事件执行的回调函数
     * @function [封装滑动事件:左滑,右滑,上滑,下滑]
     */
    swipe: function(el, dir, callback) {
        var startPoint = null, // 起始点坐标
            endPoint = null,
            distance = 30;
        // 滑动基于touchstart touchmove   touchend
        if (typeof el === 'object') {
            // 监听事件
            el.addEventListener('touchstart', function(e) {
                var touchPoint = e.touches[0]; // touch对象
                // 记录起始点坐标 startPoint
                startPoint = {
                    x: touchPoint.clientX,
                    y: touchPoint.clientY
                };

            });
            el.addEventListener('touchmove', function(e) {

                // 记录移动后的坐标,前提是有startPoint
                if (startPoint) {
                    var touchPoint = e.touches[0]; // touch对象
                    endPoint = {
                        x: touchPoint.clientX,
                        y: touchPoint.clientY
                    };
                }

            });
            el.addEventListener('touchend', function() {
                // console.log(startPoint, endPoint);
                // 调用计算滑动方向函数
                if (startPoint && endPoint && swipeDirection(startPoint, endPoint) === dir) {
                    callback && callback();
                }
                clearSwipe();

            });
            // 判断滑动方法
            /*  
                计算起始与结束的差值    
            判断滑动是水平还是垂直
            
            
            */
            function swipeDirection(start, end) {
                var diffX = end.x - start.x; // 水平差值
                var diffY = end.y - start.y; // 垂直差值
                // 求绝对值
                var absX = Math.abs(diffX);
                var absY = Math.abs(diffY);
                var direction = '';
                // 判断是否算滑动    差值  > 30
                if (absX > distance || absY > distance) {
                    // 判断水平还是垂直
                    if (absX > absY) { // 水平滑动
                        direction = diffX > 0 ? 'swipeLeft' : 'swipeRight';
                    } else {
                        direction = diffY > 0 ? 'swipeUp' : 'swipeDown';
                    }
                }
                return direction;
            }
            /*
             * @function [清除数据]
             */
            function clearSwipe() {
                startPoint = null;
                endPoint = null;
            }
        }
    }
发布了121 篇原创文章 · 获赞 151 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/feifanzhuli/article/details/90247184