【移动端debug-3】部分安卓机型不触发touchend事件的解决方案
最近在项目中遇到一个奇怪的问题,有一个需求是这样:页面上有一个按钮,滚动页面时让它消失,停止滚动时让它显示。
常规思路:
step1、监听touchstart事件,记录Touch对象中pageY初始值startY;
step2、监听touchmove事件,记录Touch对象中pageY的变化后的值endY,当大于(endY-startY)的绝对值大于某个阈值时隐藏按钮;
step3、监听touchend事件,当触发touchend时,展现按钮
代码如下:
var startY,endY;
$("body").on("touchstart", touchStartRecord)
.on("touchmove", touchMoveHide)
.on("touchend", touchEndShow);
function touchStartRecord(event){
var touch = event.touches[0];
startY = touch.pageY;
};
function touchMoveHide(event){
var touch = event.touches[0];
endY = touch.pageY;
if (Math.abs(endY - startY) >= 5) {
//此处省略隐藏按钮的操作
}
};
function touchEndShow(event){
//此处省略重新展现按钮的操作
};
我们想得思路很清晰简洁,并且在iPhone上能顺利实现我们要的效果,但是尼玛到了安卓上,手指离开屏幕后,竟然按钮没有展现!!??WTF!
用工具调试,发现在触发touchend事件的函数里打断点,竟然进不去!!!
所以产生这一问题的原因找到了:touchend事件未被触发!
如何解决?
在stackoverflow上已经有相关话题的讨论,不少人提到,这个问题由来已久,已经给谷歌提bug了(谷歌传送门:WebView touchevents are not fired propperly if e.preventDefault() is not used on touchstart and touchmove),但是最新的安卓版本还是没修复……再次WTF!!!
在讨论中有提到如下两种解决方案:
解决方案1:
在监听touchstart或者touchmove事件的函数里,阻止事件的默认行为event.preventDefault(),那么到touchend就能正常触发。
代码如下:
var startY,endY;
$("body").on("touchstart", touchStartRecord)
.on("touchmove", touchMoveHide)
.on("touchend", touchEndShow);
function touchStartRecord(event){
var touch = event.touches[0];
startY = touch.pageY;
};
function touchMoveHide(event){
var touch = event.touches[0];
endY = touch.pageY;
if (Math.abs(endY - startY) >= 5) {
//此处省略隐藏按钮的操作
event.preventDefault();
}
};
function touchEndShow(event){
//此处省略重新展现按钮的操作
};
尼玛,滚不动了啊……由于移动端touchmove事件的默认行为就是滚动页面,我们给阻止掉了,touchend是触发了,但是不是我们想要的效果。第三次WTF!!!
国外知名插件mobiscroll的博客里有分享关于这个问题的一些处理经验:(传送门:Working with touch events)
On Android ICS if no preventDefault is called on touchstart or the first touchmove, furthertouchmove events and the touchend will not be fired. As a workaround we need to decide in the first touchmove if this is a scroll (so we don’t call preventDefault) and then manually trigger touchend。
大意是:在安卓4.0系统(即Android ICS系统),如果在touchstart和第一个touchmove触发时,没有调用preventDefault,那么后面touchmove(连续触发)以及最后的touchend都不会被触发。所以我们需要决定第一个touchmove是否是一个滚动事件(如果是,则不能preventDefault阻止默认行为)然后手动触发touchend。
解决方案2:
同时绑定touchcancel和touchend事件,这样在安卓上就能通过触发touchcancel来重新展示我们的按钮。
在touchcancel却能正常触发,而在我们的这个需求里,touchcancel的情况下,我们也是希望按钮重新展现的,那不正好就是我们想要的效果吗?
代码如下:
var startY,endY;
$("body").on("touchstart", touchStartRecord)
.on("touchmove", touchMoveHide)
.on("touchcancel touchend", touchEndShow);
function touchStartRecord(event){
var touch = event.touches[0];
startY = touch.pageY;
};
function touchMoveHide(event){
var touch = event.touches[0];
endY = touch.pageY;
if (Math.abs(endY - startY) >= 5) {
//此处省略隐藏按钮的操作
}
};
function touchEndShow(event){
//此处省略重新展现按钮的操作
};
好了,现在能够解决我们的需求了,但其实还不是最优解,因为我们如果还想给touchcancel单独增加一个操作,就不能够了。所以最根本的还是寄希望于谷歌尽早解决这个历史遗留bug。
【移动端debug-3】部分安卓机型不触发touchend事件的解决方案的更多相关文章
- 【移动端debug-4】iOS下setTimeout无法触发focus事件的解决方案
开篇总结:其实目前无法解决这个bug. 这两天做项目遇到了这个case,项目需求是打开页面的时候,input元素自动弹起键盘.由于各种方面的考虑,我们希望通过setTimeout延时200毫秒让inp ...
- 解决移动端页面滚动后不触发touchend事件
解决移动端页面滚动后不触发touchend事件 问题 在移动端页面进行优化时,一般使用touch事件替代鼠标相关事件.用的较多的是使用touchend事件替代PC端的click和mouseup事件. ...
- 移动端touchstar、touchmove、touchend 事件如果页面有滚动时不让触发 touchend 事件。
/*仅适用于内容中点击元素.对于拖动等元素,需要自行在页面处理. * 主要是绑定touchstart和touchmove事件,并判断用户按下之后手指移动了多少像素. * 如果手指移动距离小于10像素, ...
- 解决红米等手机(移动端)无法触发touchend事件
触屏事件的简单描述: js的触屏事件,主要有三个事件:touchstart,touchmove,touchend. 这三个事件最重要的属性是 pageX和 pageY,表示X坐标,Y坐标.touchs ...
- 部分安卓机型1px边框无法显示解决方法
实践发现css样式中使用1px solid 在部分安卓机型无法显示. 网上找到解决方案:使用行内样式设置边框.
- H5页面适配所有iPhone和安卓机型的六个技巧
http://www.th7.cn/web/html-css/201605/166006.shtml http://www.th7.cn/web/html-css/201601/153127.shtm ...
- 移动端开发ios和安卓兼容问题
移动端开发ios和安卓兼容问题 最近做移动端混合开的时候遇到一些安卓和iOS的兼容性问题,兼容想问题不仅在浏览器存在也在APP开发当中也会经常遇到这样的情况. 最近看了一下内容很不错的移动端开发相关的 ...
- 周记5——随机撒花特效、动态修改伪元素样式、contenteditable属性、手机端调试利器VConsole、浏览器端debug调试
记录一些小零碎知识点,以便日后查看~ 1.随机撒花特效 教师节快到了,公司的产品提出一个需求:在IM(即时聊天)聊天界面弹出教师节的祝福“广告”,用户点击“发送祝福”按钮,聊天界面会随机撒花.这里的重 ...
- h5开发安卓机型点击输入框调起输入法,输入框被键盘遮挡的解决方法
前言: 从以前的项目中找一个问题的解决方案,顺带找到了这个安卓机型调起输入法,页面没有自动上滑导致输入框被弹起的键盘遮挡的解决方案.这个问题只有安卓机型页面中的输入框处于底部(也就是底部键盘区域)的时 ...
随机推荐
- 20155308&20155316 2017-2018-1 《信息安全系统设计基础》实验一
20155308&20155316 2017-2018-1 <信息安全系统设计基础>实验一 此次实验我和黄月同学一起做了1.2.3.5项,第4项在实验课上做完了,但是没有按时提交. ...
- 20155323 2016-2017-2 《Java程序设计》第10周学习总结
20155323 2016-2017-2 <Java程序设计>第10周学习总结 教材学习内容总结 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据. 狭义的网络编程范畴就是程序 ...
- [arc062E]Building Cubes with AtCoDeer
Description 传送门 Solution 这道题直接暴力就好..毕竟只要枚举了前后两个瓷砖的方向和编号,其他瓷砖的颜色就是确定的了. 然而场上我的去重除了问题qaq. 我们钦定在立方体最前面的 ...
- 【SDOI2014】数表
题面 题解 不管$a$的限制 我们要求的东西是:($\sigma(x)$是$x$的约数个数和) $ \sum_{i=1}^n\sum_{j=1}^m\sigma(gcd(i,j)) $ 设$f(x)= ...
- [IOI2011]Race 点分治
[IOI2011]Race LG传送门 点分治板子题. 直接点分治统计,统计的时候开个桶维护下就好了. 注(tiao)意(le)细(hen)节(jiu). #include<cstdio> ...
- PHP 行为测试工具 Codeception (介绍)
原文地址:https://phphub.org/topics/25 Codeception 简介 Codeception 简单来说, 分为以下几种测试 Acceptance Tests 验收测试 Fu ...
- loj2538 「PKUWC 2018」Slay the Spire
pkusc 快到了--做点题涨涨 rp. ref我好菜啊QAQ. 可以发现期望只是一个幌子.我们的目的是:对于所有随机的选择方法(一共 \(\binom{2n}{m}\)种),这些选择方法都最优地打出 ...
- 算法笔记(c++)--关于01背包的滚动数组
算法笔记(c++)--关于01背包的滚动数组 关于01背包问题:基本方法我这篇写过了. https://www.cnblogs.com/DJC-BLOG/p/9416799.html 但是这里数组是N ...
- leetcode个人题解——#40 Combination Sum2
思路:解法和39题类似,改动了两处: 1.因为题目要求每个元素只能出现一次(不代表每个数只能有一个,因为数据中会有重复的数字),所以代码中21行搜索时下一次循环的位置+1: 2.将临时存放答案的vec ...
- 《Linux内核与分析》第四周
20135130王川东 一.用户态.内核态和中断处理过程 CPU的几种不同的执行级别: 高执行级别下,代码可以执行特权指令,访问任意的物理地址,这种执行级别对应内核态: 低级别执行状态下,代码的掌握范 ...