如何修复移动浏览器上 滑动后touchend不触发 事件不触发的bug

网页设计教程与开发
提供各种常见网页效果
提供各种各样的设计教程
装扮QQ,让QQ变得更酷
设计参考,提高自升水平
学习服务器和操作系统
提供各种素材和工具
收藏学习资料
您现在的位置:&&>>&&>>&&>>&&>>&正文
浅谈javascript的Touch事件
js的touch事件,一般用于移动端的触屏滑动
代码如下:$(function(){document.addEventListener("touchmove", _touch, false);}) function _touch(event){alert(1);}
touchstart:当手指触摸屏幕时触发;即使已经有一个手指放在了屏幕上也会触发。
touchmove:当手指在屏幕上滑动时连续的触发。在这个事件发生期间,调用preventDefault()可阻止滚动。
touchend:当手指从屏幕上移开时触发。
touchcancel:当系统停止跟踪触摸时触发。关于此事件的确切触发事件,文档中没有明确说明。
以上事件的event对象上面都存在如下属性:
touches:表示当前跟踪的触摸操作的Touch对象的数组。
targetTouches:特定于事件目标的Touch对象的数组。
changeTouches:表示自上次触摸以来发生了什么改变的Touch对象的数组。
每个Touch对象包含下列属性:
clientX:触摸目标在视口中的X坐标。
clientY:触摸目标在视口中的Y坐标。
identifier:表示触摸的唯一ID。
pageX:触摸目标在页面中的x坐标。
pageY:触摸目标在页面中的y坐标。
screenX:触摸目标在屏幕中的x坐标。
screenY:触摸目标在屏幕中的y坐标。
target:触摸的DOM节点坐标
三种在规范中列出并获得跨移动设备广泛实现的基本触摸事件:
&&&& 1. touchstart:手指放在一个DOM元素上。
&&&& 2. touchmove:手指拖曳一个DOM元素。
&&&& 3. touchend:手指从一个DOM元素上移开。
每个触摸事件都包括了三个触摸列表:
&&&& 1. touches:当前位于屏幕上的所有手指的一个列表。
&&&& 2. targetTouches:位于当前DOM元素上的手指的一个列表。
&&&& 3. changedTouches:涉及当前事件的手指的一个列表
&&& 例如,在一个touchend事件中,这就会是移开的手指。
这些列表由包含了触摸信息的对象组成:
&&&& 1. identifier:一个数值,唯一标识触摸会话(touch session)中的当前手指。
&&&& 2. target:DOM元素,是动作所针对的目标。
&&&& 3. 客户/页面/屏幕坐标:动作在屏幕上发生的位置。
&&&& 4. 半径坐标和 rotationAngle:画出大约相当于手指形状的椭圆形。
可触控应用&&
&&&& touchstart、touchmove和touchend事件提供了一组足够丰富的功能来支持几乎是任何类型的基于触摸的交互――其中包括常见的多点触摸手势,比如说捏缩放、旋转等待。&&& 下面的这段代码让你使用单指触摸来四处拖曳一个DOM元素:
var obj = document.getElementByIdx_x_x_x_x_x_x('id');
obj.addEventListener('touchmove', function(event)
{ // 如果这个元素的位置内只有一个手指的话
if (event.targetTouches.length == 1)
var touch = event.targetTouches[0];
// 把元素放在手指所在的位置
obj.style.left = touch.pageX + 'px';
obj.style.top = touch.pageY + 'px';
}, false);
&&&&& 下面是一个示例,该例子显示了屏幕上当前所有的触点,它的作用就是用来感受一下设备的响应性。
// 设置画布并通过ctx变量来暴露上下文复制代码
canvas.addEventListener('touchmove',
function(event) {
for (var i = 0; i & event.touches. i++) {
var touch = event.
ctx.beginPath();
ctx.arc(touch.pageX, touch.pageY, 20, 0, 2*Math.PI, true);
ctx.fill();
ctx.stroke();
}, false);
&&&&& 到处都有着许多有意思的多点触摸演示,比如说这个由Paul Irish和其他人实现的基于画布的绘画演示。
&&&&& 还有Browser Ninja,一个技术演示,是一个使用了CSS3的转换、过渡和画布的Fruit Ninja克隆。
&&&& 缺省的多点触摸设置不是特别的好用,因为你的滑动和手势往往与浏览器的行为有关联,比如说滚动和缩放。
&&&& 要禁用缩放功能的话,使用下面的元标记设置你的视图区(viewport),这样其对于用户来说就是不可伸缩的了:
&&&& content="width=device-width, initial-scale=1.0, user-scalable=no"&
&&&& 看看这篇关于移动HTML 5的文章,了解更多关于视图区设置的信息。
&&&& 一些移动设备有缺省的touchmove行为,比如说经典的iOS overscroll效果,当滚动超出了内容的界限时就引发视图反弹。这种做法在许多多点触控应用中会带来混乱,但要禁用它很容易。
document.body.addEventListener('touchmove', function(event) {
event.preventDefault();
}, false);
&&&& 如果你正在编写的多点触控应用涉及了复杂的多指手势的话,要小心地考虑如何响应触摸事件,因为一次要处理这么多的事情。考虑一下前面一节中的在屏幕上画出所有触点的例子,你可以在有触摸输入的时候就立刻进行绘制:
canvas.addEventListener('touchmove', function(event) {
renderTouches(event.touches);
&&& 不过这一技术并不是要随着屏幕上的手指个数的增多而扩充,替代做法是,可以跟踪所有的手指,然后在一个循环中做渲染,这样可获得更好的性能:
var touches = []
canvas.addEventListener('touchmove', function(event) {
touches = event.
}, false);
// 设置一个每秒60帧的定时器
timer = setInterval(function() {
renderTouches(touches);
&&&& 提示:setInterval不太适合于动画,因为它没有考虑到浏览器自己的渲染循环。现代的桌面浏览器提供了requestAnimationFrame这一函数,基于性能和电池工作时间原因,这是一个更好的选择。一但浏览器提供了对该函数的支持,那将是首选的处理事情的方式。
使用targetTouches和changedTouches
&&& 要记住的一点是,event.touches是与屏幕接触的所有手指的一个数组,而不仅是位于目标DOM元素上的那些。你可能会发现使用 event.targetTouches和event.changedTouches来代替event.touches更有用一些。
&&& 最后一点,因为你是在为移动设备做开发,因此你应该要留心移动的最佳做法,这些在Eric Bidelman的文章中有论及,以及要了解这一W3C文档。
设备支持&&&&&
&&& 遗憾的是,触摸事件的实现在完备性和质量方面的差别很大。我编写了一个诊断脚本来显示一些关于触摸API实现的基本信息,其中包括哪些事件是支持的,以及 touchmove事件触发的解决方案。我在Nexus One和Nexus S硬件上测试了Android2.3.3,在Xoom上测试了Android 3.0.1,以及在iPad和iPhone上测试了iOS 4.2。
&&& 简而言之,所有被测试的浏览器都支持touchstart、touchend和touchmove事件。
&&& 规范提供了额外的三个触摸事件,但被测试的浏览器没有支持它们:
&&&&& 1. touchenter:移动的手指进入一个DOM元素。
&&&&& 2. toucheleave:移动手指离开一个DOM元素。
&&&&& 3. touchcancel:触摸被中断(实现规范)。
&&&& 被测试的浏览器还在每个触摸列表内部都提供了touches、targetTouches和changedTouches列表。不过,被测试的浏览器没有支持radiusX、radiusY或是rotationAngle属性,这些属性指明触摸屏幕的手指的形状。在一次touchmove期间,事件大约一秒钟触发60次,所有的被测试设备都是这样。
转载请注明:破洛洛(谢谢合作)
上一篇文章: 下一篇文章:
网友评论:
[][][][][][][][][][]下次自动登录
现在的位置:
& 综合 & 正文
移动端WEB开发,click,touch,tap事件浅析
一、click 和 tap 比较
两者都会在点击时触发,但是在手机WEB端,click会有 200~300 ms,所以请用tap代替click作为点击事件。
singleTap和doubleTap 分别代表单次点击和双次点击。
二、关于tap的点透处理
在使用zepto框架的tap来移动设备浏览器内的点击事件,来规避click事件的延迟响应时,有可能出现点透的情况,即点击会触发非当前层的点击事件。
处理方式:
github上有一个叫做fastclick的库,它也能规避移动设备上click事件的延迟响应,
将它用script标签引入页面(该库支持AMD,于是你也可以按照AMD规范,用诸如require.js的模块加载器引入),并且在dom ready时初始化在body上,如:
$(function(){
newFastClick(document.body);
然后给需要“无延迟点击”的元素绑定click事件(注意不再是绑定zepto的tap事件)即可。
当然,你也可以不在body上初始化它,而在某个dom上初始化,这样,只有这个dom和它的子元素才能享受“无延迟”的点击
实践开发中发现,当元素绑定fastclick后,click响应速度比tap还要快一点点。哈哈
(2)、为元素绑定touchend事件,并在内部加上e.preventDefault();
$demo.on('touchend',function(e){
$demo.hide()
e.preventDefault();
三、touch事件touch是针对触屏手机上的触摸事件。现今大多数触屏手机webkit内核提供了touch事件的监听,让开发者可以获取用户触摸屏幕时的一些信息。
其中包括:touchstart,touchmove,touchend,touchcancel 这四个事件
touchstart,touchmove,touchend事件可以类比于mousedown,mouseover
,mouseup的触发。
touchstart : 当手指触摸到屏幕会触发;
touchmove : 当手指在屏幕上移动时,会触发;
touchend : 当手指离开屏幕时,会触发;
而touchcancel许多人不知道它在什么时候会被触发而忽略它,其实当你的手指还没有离开屏幕时,有系统级的操作发生时就会触发touchcancel,例如alert和confirm弹框,又或者是android系统的功能弹窗。
这4个事件的触发顺序为:
touchstart -& touchmove
-& …… -& touchmove -&touchend
但是单凭监听上面的单个事件,不足以满足我们去完成监听在触屏手机常见的一些手势操作,如双击、长按、左右滑动、缩放等手势操作。需要组合监听这些事件去封装对这类手势动作。
其实市面上很多框架都针对手机浏览器封装了这些手势,例如jqmobile、zepto、jqtouch,不过悲剧发生了,对于某些android系统(我自己测试到的在android 4.0.x),touchmove和touchend事件不能被很好的触发,举例子说明下:
比如手指在屏幕由上向下拖动页面时,理论上是会触发 一个 touchstart ,很多次 touchmove
,和最终的 touchend ,可是在android 4.0上,touchmove只被触发一次,触发时间和touchstart
差不多,而touchend直接没有被触发。这是一个非常严重的bug,在google Issue已有不少人提出
暂时我只发现在android 4.0会有这个bug,据说 ios 3.x的版本也会有。
而显然jqmobile、zepto等都没有意识到这个bug对监听实现带来的严重影响,所以在直接使用这些框架的event时,或多或少会出现兼容性问题!
&&&&推荐文章:
【上篇】【下篇】今天看啥 热点:
移动端上下滑动事件之--坑爹的touch.js,touch.js
移动端页面的盛行,微信的便利的页面推广等等,让越来越多的css3效果和html5在手机端大放异彩。
于是乎,各式各样的简约酷炫的html5页面层出不穷,最多的就是视差滚动+css3动画。
接下来就说说自己在搞这些页面里面碰到的一个小问题-------zepto.js里面,坑爹的touch.js的上下滑动(swipe)事件失效。
在举例之前,先科普一下如何在pc端,查看html5页面在各种分辨率的手机的展示情况。
最常见的就是利用谷歌的手机模拟器。
步骤1:打开谷歌浏览器,按F12.
步骤2:然后按截图里面的步骤,选择各种分辨率,在刷新一下页面,就可以看到效果。
注:各种手机的选择
开始描述问题之前,先提供几个网址,
让你们试试能不能看到效果。
.cn:8080/zhaopin/index.htm?from=singlemessage&isappinstalled=0
/wechat/index.html?from=singlemessage&isappinstalled=0
/h5/index.html?from=singlemessage&isappinstalled=0
能在谷歌模拟器看到不同分辨率的效果。截几个图看一下。
好了,进入正题。
做这类html5页面,最主要的事件就是滑动事件。
分别是左右滑动和上下滑动。
说到这里,可能很多人都会脱口而出。用zepto.js就可以简单搞定啦。
我也是这么想的。于是很快的,就用zepto.js加上它的touch组件,touch.js实现了相应的效果。
在谷歌浏览器的模拟器也能很好的兼容。
后来放上测试服务器,用手机一看,问题来了!!!!
手机上的uc,腾讯,微信自带浏览器,QQ自带浏览器器,苹果系统的浏览器,安卓的原生浏览器,上下滑动的事件都失效!
只有谷歌浏览器是有事件相应的。坑爹啊!!!!
zepto.js用的人估计不少,想不到touch.js竟然兼容这么差,还是我打开的方式不对?!!!
这里就不贴这个js里面的代码出来了。
遇到问题,只好寻求其他解决方法。
解决方法先列几个吧。
第一个:jquery mobile里面的touch组件。
第二个:百度的童鞋们实现的touch.js.网址也贴一下吧:http://touch./
第三个就是技术群里面的一些童鞋提供,亲测是有效的:
(function($) {
var options, Events, T
options = {
Events = ['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'tap', 'longTap', 'drag'];
Events.forEach(function(eventName) {
$.fn[eventName] = function() {
var touch = new Touch($(this), eventName);
touch.start();
if (arguments[1]) {
options = arguments[1]
return this.on(eventName, arguments[0])
Touch = function() {
var status, ts, tm,
this.target = arguments[0];
this.e = arguments[1]
Touch.prototype.framework = function(e) {
e.preventDefault();
if (e.changedTouches) events = e.changedTouches[0];
else events = e.originalEvent.touches[0];
return events
Touch.prototype.start = function() {
var self =
self.target.on(&touchstart&,
function(event) {
event.preventDefault();
var temp = self.framework(event);
var d = new Date();
self.ts = {
x: temp.pageX,
y: temp.pageY,
d: d.getTime()
self.target.on(&touchmove&,
function(event) {
event.preventDefault();
var temp = self.framework(event);
var d = new Date();
self.tm = {
x: temp.pageX,
y: temp.pageY
if (self.e == &drag&) {
self.target.trigger(self.e, self.tm);
self.target.on(&touchend&,
function(event) {
event.preventDefault();
var d = new Date();
if (!self.tm) {
self.tm = self.ts
self.te = {
x: self.tm.x - self.ts.x,
y: self.tm.y - self.ts.y,
d: (d - self.ts.d)
self.factory()
Touch.prototype.factory = function() {
var x = Math.abs(this.te.x);
var y = Math.abs(this.te.y);
var t = this.te.d;
var s = this.
if (x & 5 && y & 5) {
if (t & 300) {
s = &longTap&
} else if (x & options.x && y & options.y) {
if (t & 250) {
if (this.te.y & 0) {
s = &swipeDown&
s = &swipeUp&
s = &swipe&
} else if (y & options.y && x & options.x) {
if (t & 250) {
if (this.te.x & 0) {
s = &swipeLeft&
s = &swipeRight&
s = &swipe&
if (s == this.e) {
this.target.trigger(this.e);
})(window.jQuery || window.Zepto);
总结:为什么要把这个作为一篇博客发出去,就是因为之前碰到这个问题的时候,问度娘问谷歌都很少答案。所以把这个小问题说出来,让碰到类似问题的童鞋,能够有一些启发。
Author: Alone
Antroduction: 高级前端开发工程师
Sign: 人生没有失败,只有没到的成功。
博主相关文章推荐:
轻轻谈一下seaJs——模块化开发的利器
有趣的前端题目,看了不后悔
移动端前端开发概述
标签的语义化
浅谈鼠标滚轮事件
不积跬步无以至千里----高度自适应的textarea
sass和less,优秀的前端样式预处理器
视差滚动的那些事儿
关于那些常见的坑爹的小bug
简单的做法:首先设置元素出状态 top (js 的 clientHeight)利用 css3 transition,(例:transition: top .2s ease)然后通过事件改变 top 的值,达到滑动的效果(top: client页面高度 -& top: 0)(以上仅为参考,该元素需要 position: fixed)复杂的可以再去上网寻找下各种例子,甚至是尝试模仿一些app的效果自己做点东西出来
侦听ontouchstart事件,记录初始的坐标值在ontouchmove事件中,持续监测移动的距离,即可作出下一步的操作
相关搜索:
相关阅读:
相关频道:
&&&&&&&&&&&&&&&&&&
WEB前端教程最近更新推荐这篇日记的豆列
······

我要回帖

更多关于 touchend 不触发 的文章

 

随机推荐