2

在移动端开发中,现有的手势事件只有IOS上的浏览器支持,因此对其他设备上的浏览器手势事件我们必须在移动端的touchstart、toucmove、touchend事件上进行改造升级,下面就介绍下升级改造的移动端的手势事件。

移动端触摸事件(基础事件)

  • touchstart--- 触摸开始
  • touchmove--- 触摸移动
  • touchend--- 触摸结束
  • touchcancel--- 触摸中断(在触摸过程中被打断,如弹框)
box.addEventListener('touchmove',function (event) {
    console.log('触摸移动');
}

touchEvent对象

  • touches---触发事件时屏幕上的触点个数
  • targetTouches---触发事件时事件元素上的触点个数
  • changedTouches---触发事件发生改变的触点个数
  • target ---事件元素
  • stopPropagation() ---阻止事件冒泡
  • preventDefault() ---阻止默认行为

touchlist对象

touchEvent对象的集合,类数组对象;
targetTouches、touches、changedTouches属性返回的都是touchlist对象

touch对象

  • clientX/clientY---触点在视口上的位置
  • pageX/pageY---触点在页面上的位置
  • screenX/screenY---触点在屏幕上的位置
 box.addEventListener('touchstart',function (event) {
    console.log(event.touches);  //一个手指触摸时输出   Touchlist{0:Touch,length:1}
    var startX = event.touches[0].clientX; //触点在视口上的位置
 }

手势事件

IOS的手势事件

1.1 事件

  • gesturestart---手势开始,手指触碰当前元素,屏幕上有两个或者两个以上的手指
  • gesturechange---手势变化,手指触碰当前元素,屏幕上有两个或者两个以上的手指位置在发生移动
  • gestureend---手势结束,在gesturestart后, 屏幕上只剩下两根以下(不包括两根)的手指

1.2 touchEvent 新增的属性

  • scale 触点的距离与触点初始距离的比例
  • rotation 触点的角度差与初始角度差的差
 box.addEventListener('gesturechange', function(event){
    box.innerHTML = 'rotation : '+event.rotation + '<br>';
    box.innerHTML += 'scale : '+event.scale + '<br>';
 });

移动端手势事件(多指事件)

//封装 gestrue.js插件
(function (w) {
    /**
     * 用于给元素监听手势事件
     * @param node  要监听的元素
     * @param callback 对象,对象有三个函数 start、change、end
     */
    function gesture(node, callback) {
        //手势开始
        // 当开始触摸元素的时候,判断屏幕上手指个数 >= 2
        node.addEventListener('touchstart', function(event) {
            if (event.touches.length >= 2) {
                //标记已经触发了手势开始
                node.isGestureStart = true;
                //计算一下两个触点的初始距离
                this.startDst = getDst(event.touches[0], event.touches[1]);
                //计算一下两个触点的初始角度
                this.startDeg = getDeg(event.touches[0], event.touches[1]);
                // 调用回调函数
                if (callback && typeof(callback['start']) === 'function') {
                    callback['start']();
                }
            }
        });

        // 手势移动
        // 当有手指移动的时候,判断屏幕上手指的个数 >= 2
        node.addEventListener('touchmove', function(event) {
            if (event.touches.length >= 2) {
                // 计算当前两个触点的距离
                var currentDst = getDst(event.touches[0], event.touches[1]);
                // 计算书两个触点的当前的夹角角度
                var currentDeg = getDeg(event.touches[0], event.touches[1]);
                // 计算当前两个触点的距离 和 两个触点的初始距离 比例
                event.scale = currentDst / this.startDst;
                // 计算两个触点,夹角的变化
                event.rotation = currentDeg - this.startDeg;
                //调用回调函数
                if (callback && typeof(callback['change']) === 'function') {
                    callback['change'](event);
                }
            }
        });

        // 手势结束
        // 触发过手势开始并且有触摸结束的时候判断屏幕上手指数量 < 2
        node.addEventListener('touchend', function(event) {
            if (node.isGestureStart && event.touches.length < 2) {
                //重置标记
                node.isGestureStart = false;
                //调用回调函数
                if (callback && typeof(callback['end']) === 'function') {
                    callback['end']();
                }
            }
        });

        /**
         * 计算两个触点的位置
         * @param touch1 第一个触点
         * @param touch2 第二个触点
         */
        function getDst(touch1, touch2) {
            //计算两个直角边的长度
            var x = touch2.clientX - touch1.clientX; //水平方向的距离
            var y = touch2.clientY - touch1.clientY; //垂直方向的距离
            //利用勾股定理,计算两个触点的距离(斜边的长度)
            var z = Math.sqrt(x*x + y*y);
            // 返回结果
            return z;
        }

        /**
         * 计算两个触点的夹角(水平辅助线)的角度
         * @param touch1 第一个触点
         * @param touch2 第二个触点
         */
        function getDeg(touch1, touch2) {
            //计算两个触点的距离,两个直角边长度
            var x = touch2.clientX - touch1.clientX; //临边
            var y = touch2.clientY - touch1.clientY; //对边
            //根据两个直角边比例 tan,计算角度
            var angle = Math.atan2(y, x); //是个弧度
            //根据弧度计算角度
            var deg = angle / Math.PI * 180;
            //返回角度
            return deg;
        }
    }

    //暴露
    w.gesture = gesture;
    
})(window);

使用案例-实现元素缩放及旋转

<!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,viewport-fit:cover">
    <title>元素缩放及旋转</title>
    <style>
        * {
            margin:0;
            padding:0;
        }
        html,body,#app {
            width: 100%;
            height: 100%;
            overflow: hidden;
        }
        #box {
            position: absolute;
            left: 0;
            top: 0;
            right: 0;
            bottom: 0;
            margin: auto;
            width: 150px;
            height: 150px;
            background-color: #f90;
        }
    </style>
</head>
<body>
    <div id="app">
        <div id="box"></div>
    </div>
    **transformcss.js代码可查看笔者的'transform函数'文章**
    <script src="js/transformcss.js"></script>
    <script src="js/gestrue.js"></script>
    <script>
        (function () {
            //获取元素
            var app = document.querySelector('#app');
            var box = document.querySelector('#box');

            //阻止浏览器默认行为
            app.addEventListener('touchstart', function(event) {
                event.preventDefault();
            });
            
            gesture(box, {
                start: function(){
                    //记录开始手势的时候,此时元素的缩放比例
                    box.startScale = transformCss(box, 'scale');  //默认为1
                    //计算开始手势的时候,此时元素的初始旋转角度
                    box.startRotate = transformCss(box, 'rotate'); //默认为0
                },
                change: function(event){
                    //实现缩放
                    transformCss(box, 'scale', box.startScale * event.scale);
                    //实现旋转
                    transformCss(box, 'rotate', box.startRotate + event.rotation)
                }
            });
        })();
    </script>

说明:笔者只是个在前端道路上默默摸索的初学者,若本文涉及错误请及时给予纠正,如果本文对您有帮助的话,点击铭哥哥网址 http://learn.fuming.site/ 学习更多!


捕猹少年闰土
42 声望0 粉丝