首页 > 网站 > WEB开发 > 正文

javascript 常用手势 分析

2024-04-27 14:13:45
字体:
来源:转载
供稿:网友

javascript 常用手势 分析

Javascript 常用手势, 个人觉得有3个 tap,swipe(swipeLeft,swipeRight,swipeTop,swipeRight),hold

tap 是轻击 判断的原则是,在toustart后,移动范围不超过10px(圆的范围),就算是 轻击了

swipe 是轻滑(轻扫) 判断在toustart后,时间间隔小于300ms,移动范围大于20,就判断是轻滑

hold(常按) 按住 移动范围小于10px,时间大于200ms,就认为他是hold

自定义手势,网上相关的源码很多,我也找了一个来研究,叫touch.js,挺不错的支持pc端,移动端(移动端就是touchstart,pc端就是mousedown),虽然有些小bug,比如事件删除有问题

touch.js的地址 http://touch.code.baidu.com/

一些要准备的基础

手势的基本实现原理

阉割源码解析

支持移动端 pc端的阉割源码解析

zepto的手势源码解析

一些我遇到的手势问题

一些要准备的基础

1.对touch相关的东西要了解

指尖上的js是很好的东西呀

指尖上的js一

指尖上的js二

指尖上的js三

2.自定义事件CustomEvent

dom是添加自定义事件的,也可以触发它,它还以冒泡

火狐的一个官方说明 官方说明

一篇比较详细的介绍,还有例子点点点

自定义事件是可以用Chrome看到的,如图

手势的基本实现原理

tap,hold,swipe都是js没有的事件,都是由,touchstart,touchmove,touchend touchcancel这些事件组合而成的

实现原理就是通过绑定document的”touchstart touchmove touchend touchcancel“事件

当touch到元素,查看手势是否符合tap,swipe的原则

如果符合原则,就触发元素绑定的相关事件

判断移动了多少位置

比如我点击了元素a,我就就得记下点击时的位置,计算方式如下

touches[0].pageX,touches[0].pageY

这个是手指点击的位置离页面顶端的位置(或者是页面的左边)

然后再touchmove时记下相关的位置

在touchend或者touchcancel时,用2个数据,算一下移动了多少就行了

ps:touchend和touchcancel是没有event的所以必须在touchmove里面记录位置

阉割源码解析

touch.js 以我的水平来看,并不能很流畅的阅读源码...

而且有些手势也不是很常用,做了些阉割,写了些注释,方便理解

<html><head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">    <title>wo ca!~</title>    <meta name="apple-mobile-web-app-capable" content="yes">    <meta name="apple-mobile-web-app-status-bar-style" content="black">    <meta name="format-detection" content="telephone=no"></head><style>    .xx{width: 200px;background: #ccc; height: 100px;}</style><body><div id="vv" class="xx"></div><br><div id="ss" class="xx"></div><br><div id="ss1" class="xx">1</div><br><div id="ss2" class="xx">1</div><br><div id="ss3" class="xx"></div><br><div id="ss4" class="xx"></div><script>    (function(){        var utils = {};        //获取元素的点击位置        utils.getPosOfEvent = function(ev){            var posi = [];            var src = null;            for (var t = 0, len = ev.touches.length; t < len; t++) {                src = ev.touches[t];                posi.push({                    x: src.pageX,                    y: src.pageY                });            }            return posi;        }        utils.getType = function(obj) {            return Object.PRototype.toString.call(obj).match(//s([a-z|A-Z]+)/)[1].toLowerCase();        };        //获取点击的手指数量                utils.getFingers = function(ev) {            return ev.touches ? ev.touches.length : 1;        };        utils.isTouchMove = function(ev) {            return ev.type === 'touchmove';        };        //是否已经结束了手势        utils.isTouchEnd = function(ev) {            return (ev.type === 'touchend' || ev.type === 'touchcancel');        };        //算2点之间的距离                utils.getDistance = function(pos1, pos2) {            var x = pos2.x - pos1.x,                y = pos2.y - pos1.y;            return Math.sqrt((x * x) + (y * y));        };        //算角度        utils.getAngle = function(p1, p2) {            return Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;        };        //根据角度 返回up down left right        utils.getDirectionFromAngle = function(agl) {            var directions = {                up: agl < -45 && agl > -135,                down: agl >= 45 && agl < 135,                left: agl >= 135 || agl <= -135,                right: agl >= -45 && agl <= 45            };            for (var key in directions) {                if (directions[key]) return key;            }            return null;        };        utils.reset = function() {            startEvent = moveEvent = endEvent = null;            __tapped = __touchStart = startSwiping = false;            pos = {start: null,move: null,end: null};        };        //ua        utils.env = (function() {            var os = {}, ua = navigator.userAgent,                android = ua.match(/(Android)[/s//]+([/d/.]+)/),                ios = ua.match(/(iPad|iPhone|iPod)/s+OS/s([/d_/.]+)/),                wp = ua.match(/(Windows/s+Phone)/s([/d/.]+)/),                isWebkit = /WebKit//[/d.]+/i.test(ua),                isSafari = ios ? (navigator.standalone ? isWebkit : (/Safari/i.test(ua) && !/CriOS/i.test(ua) && !/MQQBrowser/i.test(ua))) : false;            if (android) {                os.android = true;                os.version = android[2];            }            if (ios) {                os.ios = true;                os.version = ios[2].replace(/_/g, '.');                os.ios7 = /^7/.test(os.version);                if (ios[1] === 'iPad') {                    os.ipad = true;                } else if (ios[1] === 'iPhone') {                    os.iphone = true;                    os.iphone5 = screen.height == 568;                } else if (ios[1] === 'iPod') {                    os.ipod = true;                }            }            if (isWebkit) {                os.webkit = true;            }            if (isSafari) {                os.safari = true;            }            return os;        })();                //已配置  tap hold swipe表示是否开启手势        //tapTime tap事件延迟触发的时间        //holdTime  hold事件多少秒后触发        //tapMaxDistance 触发tap的时候 最小的移动范围        //swipeMinDistance 触发swipe的时候 最小的移动范围        //swipeTime  touchstart 到touchend之前的时间 如果小于swipeTime  才会触发swipe手势        var config = {            tap: true,            tapMaxDistance: 10,            hold: true,            tapTime: 200,            holdTime: 650,            swipe: true,            swipeTime: 300,            swipeMinDistance: 18        };        var smrEventList = {            TOUCH_START: 'touchstart',            TOUCH_MOVE: 'touchmove',            TOUCH_END: 'touchend',            TOUCH_CANCEL: 'touchcancel',            SWIPE_START: 'swipestart',            SWIPING: 'swiping',            SWIPE_END: 'swipeend',            SWIPE_LEFT: 'swipeleft',            SWIPE_RIGHT: 'swiperight',            SWIPE_UP: 'swipeup',            SWIPE_DOWN: 'swipedown',            SWIPE: 'swipe',            HOLD: 'hold',            TAP: 'tap',        };        /** 手势识别 */        //记录 开始 移动 结束时候的位置        var pos = {            start: null,            move: null,            end: null        };        var __touchStart = true;        var __tapped;        var __prev_tapped_end_time;        var __prev_tapped_pos;        var __holdTimer = null;        var startTime;        var startEvent;        var moveEvent;        var endEvent;        var startSwiping;        var gestures = {            swipe: function(ev) {                var el = ev.target;                if (!__touchStart || !pos.move || utils.getFingers(ev) > 1) {                    return;                }                   //计算 时间  距离  角度                var now = Date.now();                var touchTime = now - startTime;                var distance = utils.getDistance(pos.start[0], pos.move[0]);                var angle = utils.getAngle(pos.start[0], pos.move[0]);                var direction = utils.getDirectionFromAngle(angle);                var touchSecond = touchTime / 1000;                var eventObj = {                    type: smrEventList.SWIPE,                    originEvent: ev,                    direction: direction,                    distance: distance,                    distanceX: pos.move[0].x - pos.start[0].x,                    distanceY: pos.move[0].y - pos.start[0].y,                    x: pos.move[0].x - pos.start[0].x,                    y: pos.move[0].y - pos.start[0].y,                    angle: angle,                    duration: touchTime,                    fingersCount:
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表