打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
2016/9/30 从移动端touch事件谈起
移动互联网终端的touch事件

touchstart 手指触摸屏幕的时候执行
touchmove 手指在屏幕上移动的时候执行
touchend 手指离开屏幕的时候执行
touchcancel 事件被强制终止的时候执行 (来电话了 短信 按home)

每个触摸事件都包括了三个触摸列表:
  1. touches :当前位于屏幕上的所有手指的一个列表。
  2. targetTouches :位于当前DOM元素上的手指的一个列表。
  3. changedTouches :涉及当前事件的手指的一个列表。
    这些列表由包含了触摸信息的对象组成:
    1. identifier :一个数值,唯一标识触摸会话(touch session)中的当前手指。
    2. target :DOM元素,是动作所针对的目标。
    3. 客户/页面/屏幕坐标 :动作在屏幕上发生的位置。
    4. 半径坐标和 rotationAngle :画出大约相当于手指形状的椭圆形。

深入了解touch事件之前 有必要先了解 touch对象 ;

touch对象用来封装一次屏幕触摸,一般来自于手指。
它在touch事件触发的时候产生,可以通过touch事件处理器(event handler)机制的event对象取到;(一般是通过event.changedTouches属性)。
这个对象包括一些重要的属性:

client  / clientY:触摸点相对于浏览器窗口viewport的位置pageX / pageY:触摸点相对于页面的位置screenX /screenY:触摸点相对于屏幕的位置identifier: touch对象的unique ID
移动平台 对meta标签的定义(很多种 ,先了解一种写法)
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />user-scalable – // 用户是否可以手动缩放 (no,yes)maximum-scale – // 允许用户缩放到的最大比例initial-scale – // 初始的缩放比例 (范围从 > 0 到 10)

demo1

一个div;手指触摸时显示 ;手指移动 div也跟着移动 ;手指离开 div消失

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport"   content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>    <title>touch</title>    <style>        html,body,div{            margin: 0;            padding: 0;        }        #box{            width: 50px;            height: 50px;            background-color: pink;            display: none;            position: absolute;        }        .show{            //权重 !important            display: block !important;        }    </style></head><body>    <div id="box">    </div>    <script>        var box = document.querySelector("#box");        document.addEventListener("touchstart",function (e) {            box.className = "show";            var touch = e.changedTouches[0];            box.style.left = touch.pageX - box.offsetWidth / 2 + "px";            box.style.top = touch.pageY -  box.offsetHeight / 2 +"px";        })        document.addEventListener("touchmove",function (e) {            var touch = e.changedTouches[0];            box.style.left = touch.pageX - box.offsetWidth / 2 + "px";            box.style.top = touch.pageY -  box.offsetHeight / 2 +"px";        })        document.addEventListener("touchend",function (e) {            box.className = "";        })    </script></body></html>

demo2
做一个入下图所示无滚动条 可左右滑动的 且无论字数间距固定 不会换行的导航栏


手机端导航栏


代码如下

<!doctype html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"/>    <title>Document</title>    <style type="text/css">        html,body,div,ul,li{            margin: 0;            padding: 0;        }        #topbar{            width: 100%;            height: 44px;            overflow: hidden;        }        #nav{            height: 55px;            overflow: auto;            background-color: #0FA9D8;        }        #nav ul{            white-space: nowrap;            /*width: auto;*/        }        #nav ul li{            display: inline-block;            height: 44px;            line-height: 44px;            padding: 0 30px;        }    </style></head><body>    <div id="topbar">        <nav id="nav">            <ul>                <li>娱乐头条</li>                <li>军事</li>                <li>历史</li>                <li>新闻</li>                <li>美图</li>                <li>旅游</li>            </ul>        </nav>    </div></body><script>    var ul = document.querySelector("ul");    ul.addEventListener("touchstart",function(e){        this.startTouch = e.changedTouches[0];    })    ul.addEventListener("touchmove",function(e){        var touch = e.changedTouches[0];        if(Math.abs(touch.pageX-this.startTouch.pageX)>10){            this.isMove = true;        }    })    ul.addEventListener("touchend",function(e){        this.endTouch = e.changedTouches[0];        if(Math.abs(this.endTouch.pageX-this.startTouch.pageX)<10 && !this.isMove){            console.log("tap")        }else{            console.log("move");        }        if (e.target.nodeName=="LI") {            console.log(e.target.innerHTML);        }    })</script></html>

有一个问题 this.startTouch = e.changedTouches[0];这个获取到的是第一次触摸的事件 ,以后 全是以此为参照 ~有时间请教下别人

待理解的touch.js

/** * Created by lovering on 16/9/20. */(function () {    var typeObj = {        tap:            true, //点击 和 抬起的位置 误差不超过容错范围 即算tap        doubleTap:      true, //两次tap 时间在300ms 之内 算doubleTap        swiperLeft:     true, //抬起的位置的X 相对于 开始的位置的 X 的差值 为正 并且 滑动距离大于某个值(40px) Y上线误差不能超过20px(误差为40px)        swiperRight:    true, //抬起的位置的X 相对于 开始的位置的 X 的差值 为负 并且 滑动距离大于某个值(40px) Y上线误差不能超过20px(误差为40px)        swiperDown:     true, //抬起的位置的Y 相对于 开始的位置的 Y 的差值 为正 并且 滑动距离大于某个值(40px) X上线误差不能超过20px(误差为40px)        swiperUp:       true  //抬起的位置的Y 相对于 开始的位置的 Y 的差值 为负 并且 滑动距离大于某个值(40px) X上线误差不能超过20px(误差为40px)    }    var eventFn = {        tap : function (e,callback) {            if (Math.abs(this._endTouch.pageX - this._startTouch.pageX) <= 5 && Math.abs(this._endTouch.pageY - this._startTouch.pageY) <= 5 && !this._isMove){                if (callback){                    callback(e);                }            }        },        doubleTap : function (e,callback) {            var t = this;            isDouble(function () {                //用自定义属性来存储点击的次数                t._tapNum += 1;                //判断是否开启过定时器 如果没开起过则进入判断 开启定时器 如果定时器开启说明当前为第二次点击                if (!t._timer){                    t._timer =  setTimeout(function () {                        //300ms后判断当前的点击次数是否为2 如果为2则说明在300ms内点击了两次                        //同时判断callback 是否存在 如存在说明外面给元素绑定过双击事件                        //两个条件都满足的情况下 则回调双击事件的回调函数.                        if (t._tapNum == 2 && callback){                            callback(e);                        }else if (t._tapNum == 1){                            //如果当前点击次数为1 说明没有进行双击 当前为单击 调用单击判断的方法 进行单击函数的回调                            eventFn.tap.call(t,e,t._evevtType["tap"]);                        }                        //不管是否在300ms 内双击 我们都需要将 点击次数清零 定时器清除 并置空 以便下个周期 从新判断使用                        t._tapNum = 0;                        clearTimeout(t._timer);                        t._timer = null;                    },300)                }            });            function isDouble(callback) {                if (Math.abs(t._endTouch.pageX - t._startTouch.pageX) <= 5 && Math.abs(t._endTouch.pageY - t._startTouch.pageY) <= 5 && !t._isMove){                    callback();                }            }        },        swiperLeft : function (e,callback) {            if (this._endTouch.pageX - this._startTouch.pageX < -40 && Math.abs(this._endTouch.pageY - this._startTouch.pageY) <= 20){                if (callback){                    callback(e);                }                // callback && callback(e);                //                // callback ? callback(e) : null;            }        },        swiperRight : function (e,callback) {            if (this._endTouch.pageX - this._startTouch.pageX > 40 && Math.abs(this._endTouch.pageY - this._startTouch.pageY) <= 20){                if (callback){                    callback(e);                }            }        },        swiperDown : function (e,callback) {            if (this._endTouch.pageY - this._startTouch.pageY > 40 && Math.abs(this._endTouch.pageX - this._startTouch.pageX) <= 20){                if (callback){                    callback(e);                }            }        },        swiperUp : function (e,callback) {            if (this._endTouch.pageY - this._startTouch.pageY < -40 && Math.abs(this._endTouch.pageX - this._startTouch.pageX) <= 20){                if (callback){                    callback(e);                }            }        }    };    HTMLElement.prototype.addEventListener = function (eventType,callback) {        if (typeObj[eventType]){            if (!this._isBind){                this._isBind = true;                this._evevtType = {};                //第一次绑定的时候设置一个自定义属性用来存储点击次数 以便后面判断双击时使用                this._tapNum = 0;                //在第一次绑定的时候 给绑定元素设置一个对象的自定义属性 以绑定的事件类型为属性名 以 对应事件类型的callback 为属性值                //把绑定过的事件进行存储.                this._evevtType[eventType] = callback;                EventTarget.prototype.addEventListener.call(this,"touchstart",function (e) {                    this._startTouch = e.targetTouches[0];                    this._isMove = false;                });                EventTarget.prototype.addEventListener.call(this,"touchmove",function (e) {                    var moveTouch = e.targetTouches[0];                    if (Math.abs(moveTouch.pageX - this._startTouch.pageX) > 5 && Math.abs(moveTouch.pageY - this._startTouch.pageY) > 5){                        this._isMove = true;                    }                });                EventTarget.prototype.addEventListener.call(this,"touchend",function (e) {                    this._endTouch = e.changedTouches[0];                    for (var key in eventFn){                        if (key != "tap"){                            eventFn[key].call(this,e,this._evevtType[key]);                        }                    }                });            }else {                //在第一次之后我们对每次绑定的事件进行存储                this._evevtType[eventType] = callback;            }        }else {            EventTarget.prototype.addEventListener.call(this,eventType,callback);        }    }    HTMLElement.prototype.removeEventListener = function (eventType,callback) {        if (typeObj[eventType]){            if (this._evevtType[eventType] && this._evevtType[eventType] == callback){                delete this._evevtType[eventType];            }        }else {            EventTarget.prototype.removeEventListener.call(this,eventType,callback);        }    }})();
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
移动端事件(二)——移动端滑屏切换的幻灯片
对于移动端浏览器touch事件的研究总结(4)判断手指滑动方向
超酷JS拖拽翻页效果.htm
针对多点触控浏览器进行的开发
指尖下的js ——多触式web前端开发之一:对于Touch的处理
web前端教程分享javascript 练习题
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服