移动互联网终端的touch事件
touchstart 手指触摸屏幕的时候执行
touchmove 手指在屏幕上移动的时候执行
touchend 手指离开屏幕的时候执行
touchcancel 事件被强制终止的时候执行 (来电话了 短信 按home)每个触摸事件都包括了三个触摸列表:
- touches :当前位于屏幕上的所有手指的一个列表。
- targetTouches :位于当前DOM元素上的手指的一个列表。
- changedTouches :涉及当前事件的手指的一个列表。
这些列表由包含了触摸信息的对象组成:
- identifier :一个数值,唯一标识触摸会话(touch session)中的当前手指。
- target :DOM元素,是动作所针对的目标。
- 客户/页面/屏幕坐标 :动作在屏幕上发生的位置。
- 半径坐标和 rotationAngle :画出大约相当于手指形状的椭圆形。
touch对象用来封装一次屏幕触摸,一般来自于手指。
它在touch事件触发的时候产生,可以通过touch事件处理器(event handler)机制的event对象取到;(一般是通过event.changedTouches属性)。
这个对象包括一些重要的属性:
client / clientY:触摸点相对于浏览器窗口viewport的位置pageX / pageY:触摸点相对于页面的位置screenX /screenY:触摸点相对于屏幕的位置identifier: touch对象的unique ID
<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)
一个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];这个获取到的是第一次触摸的事件 ,以后 全是以此为参照 ~有时间请教下别人
/** * 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); } }})();
联系客服