移动webapp的那些bug
bug持续更新中...
测试浏览器
Chrome: 61.0.3163.73
Safari: 10.0(IOS 10.3.3)
Github: webapp-bugs
1. IOS overflow: scroll 全屏滚动出界
1.1 出现场景
滑动到最顶部(最底部)的时候,停下,然后继续向上滑动(向下滑动)
1.2 解决方案
- 手动设置滑到边界时的
scrollTop
(scrollFix)
当快滑到上边界或者下边界的值时,手动设置scrollTop
与达到边界时相差一像素(上边界时:scrollTop = 1
, 下边界时:scrollTop = elem.scrollHeight - elem.offsetHeight - 1
),这样就不会触发出界的极限条件。
具体实现:
var ScrollFix = function(elem) {
// Variables to track inputs
var startY, startTopScroll;
elem = elem || document.querySelector(elem);
// If there is no element, then do nothing
if(!elem)
return;
// Handle the start of interactions
elem.addEventListener('touchstart', function(event){
startY = event.touches[0].pageY;
startTopScroll = elem.scrollTop;
if(startTopScroll <= 0)
elem.scrollTop = 1;
if(startTopScroll + elem.offsetHeight >= elem.scrollHeight)
elem.scrollTop = elem.scrollHeight - elem.offsetHeight - 1;
}, false);
};
注:1. 这个方法只能部分防止,在某些时候还是会触发出界。2. 有说在全局滚动下和局部滚动下会有差异,但是就我测试的情况来说,差异并不是特别大。可能是版本太高的原因,具体结论还待测试更多机型。
- 头部由
static
变为fixed
(测试效果貌似更好)
.toolbar {
-webkit-box-sizing: border-box;
padding: 1em;
background: #222;
color: #fff;
font-weight: bold;
text-align: center;
height: 50px;
/* 添加fixed头部 */
position: fixed;
top: 0;
z-index: 1;
width: 100%;
}
2. IOS通过脚本使输入框聚焦,无法弹出键盘
2.1 出现场景
看如下代码:
// html
<input type="email" class="form-control" id="inputEmail3" placeholder="Email">
<button id="submitBtn" class="btn btn-default">Sign in</button>
// script
var inputEmail3 = document.querySelector('#inputEmail3');
var submitBtn = document.querySelector('#submitBtn');
// way1
setTimeout(() => {
inputEmail3.focus();
}, 2000);
这种方式下:在IOS
上输入框聚焦确没有办法弹出键盘
2.2 解决方案
爬墙爬到这么一个issue,3楼eddiemonge
老哥说到了,在IOS
下除非用户手动触发了输入框的focus
事件,才会触发键盘,至于设置定时器也是不管用的;但是,手动点击一个按钮,在按钮的操作中再来执行focus
事件倒是管用的。他还给出了一个http://jsbin.com/inunis/8/edit?html,js,output
// 这样是可以弹出键盘的
submitBtn.onclick = function(e) {
e.preventDefault();
inputEmail3.focus();
}
3. IOS光标不跟随输入框移动
3.1 艰辛历程
我为什么会关注这个问题:那是因为我**(这里省略一万个草泥马)也遇到了这个问题呀,容我细细说来。
我有一个登录页面,在聚焦之后需要往上弹一下,android
上正常,然后IOS
上还同时引出了一个BUG
:输入框上去了,但是光标却在下面闪。怎么办呢?当然是靠想办法解决呀,后来我就想在输入框上贴一层蒙版,点击了之后消失,同时在点击操作中,等到动画结束之后再执行输入框的focus
,行不行呢?好期待。。。
html
代码是这样的:
// ... 这里省略若干
<div class="col-sm-10">
<input type="email" class="form-control" id="inputEmail3" placeholder="Email" />
<div class="input-overlay" id="overlay"></div>
</div>
样式:
.input-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 0, 0, 0.3);
z-index: 2;
}
脚本:
overlay.addEventListener('touchstart', function(e) {
e.preventDefault();
testForm.style.transform = 'translate3d(0, 0, 0)';
overlay.style.display = 'none';
overlay.style.zIndex = -1;
setTimeout(function() {
inputEmail3.focus();
}, 200);
});
正所谓想象是好样的,但是实际行使起来却不是那么令人满意。是的,毫无效果。后来我想,是不是可以模拟一个事件,再触发一次点击,然后代码是这样的:
function mockEvent(fn) {
var createDiv = document.createElement('div');
createDiv.style.display = 'none';
document.body.appendChild(createDiv);
// 未做兼容
var e = document.createEvent('MouseEvent');
e.initEvent('xx', true, true);
createDiv.addEventListener('xx', function() {
fn && fn();
createDiv.remove();
});
createDiv.dispatchEvent(e);
}
overlay.addEventListener('click', function(e) {
// ...
setTimeout(function() {
mockEvent(function() {
inputEmail3.focus();
});
}, 200);
});
答案依然是:不行。然后我想,是不是setTimeout
的原因,只要存在延迟的情况下就不行。结果我去这么试了一下,将之前的按钮直接点击方式改为200ms
之后执行focus
。
submitBtn.onclick = function(e) {
e.preventDefault();
setTimeout(function() {
inputEmail3.focus();
}, 200);
}
果然,只要设置延迟就不起效果了。顿时突然想到移动端点透事件貌似有个300ms
延迟执行。虽然点透事件在移动端会被处理掉,然而我只是想验证一下我的猜想。然后我又这么写:
// html
<div class="col-sm-10">
<input type="email" class="form-control" id="inputEmail3" placeholder="Email" />
<div class="input-overlay" id="overlay"></div>
<a class="input-link" href="javascript:;" id="link">link</a>
</div>
在overlay
下面放一个link
,然后在overlay
上绑定touchstart
事件,在link
上绑定click
事件。这样在上层的遮罩去掉之后,就可以300ms
后执行下面的link
层中的事情,那么也算是用户真正地触发的点击行为,美滋滋。结果我在代码中加了这个东西:
overlay.addEventListener('touchstart', function(e) {
// ...
});
link.addEventListener('click', function() {
link.style.display = 'none';
link.style.zIndex = -1;
inputEmail3.focus();
});
尼玛呀,还是不行,绝望了。
然而。。。
天生不死心,又去爬墙呀。输入inupt move while cursor to stay where it was
。下面讲解决方案。
3.2 解决方案
我找到了这样的一个issue。在其中的描述是:他的内容中有一输入框,然后focus
,当滑动内容时,光标不跟随移动,而在此输入的时候,光标又会回到输入框中。情况应该和我类似。
robby says
I also have this problem.
It is apparently related to the use of css transforms.I have fixed it with this hack workaround that forces redrawing as you scroll to eliminte this issue:
CSS:input {
text-shadow: rgba(0,0,0,0) 0px 0px 0px;
}
input.force-redraw {
text-shadow: none;
}JS:
myScroll = new iScroll('wrapper', {
onScrollMove: function() {
$('input').toggleClass('force-redraw');
}
});
是的,有木有很激动。于是我这样写:
// css
input {
text-shadow: rgba(0,0,0,0) 0px 0px 0px;
}
input.force-redraw {
text-shadow: none;
}
// javascript
inputEmail3.addEventListener('focus', function() {
testForm.style.transform = 'translate3d(0, 0, 0)';
setTimeout(() => {
inputEmail3.className = 'form-control force-redraw';
}, 300);
});
效果大体上实现了,但是仍然有瑕疵。就是必须设置延迟300ms
以上,不然,光标重绘不正常,而且光标有明显的移动过程。所以如果童鞋们如果发现有什么更好的办法,还望不吝赐教。
另外,如果一个页面中有输入框,聚焦之后,滑动过程中在IOS
上可能会出现不流畅的问题,其实可以这么做:监测页面的touchmove
事件,如果当前页面存在着输入框被active
,那么直接让其blur
,保证滑动过程中没有输入框被聚焦。(不过以我的测试情况来看,在chrome
和safari
上滑动的时候输入框不再被激活,类似在PC
端滑动的时候采用了蒙版或者points-event: none;
的效果)
var thisFocus;
var content = document.querySelector('#content');
var inputs = document.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
input.onfocus = focused;
}
function focused(e) {
thisFocus = e.target;
}
content.addEventListener('touchmove', function() {
if (thisFocus) {
thisFocus.blur();
thisFocus = null;
}
});
4. IOS输入框聚焦后页面整体上移,头部顶出
4.1 出现场景
页面中有fixed
头部,输入框,并且输入框靠下时,当输入框focus
的时候,会将整个页面上移,导致头部被顶出去。fixed position div freezes on page
4.2 解决方案
原因大致是:ios
自带的输入居中效果,而带有fixed
头部在页面被顶上去的同时没有重新计算位置,导致显示错误。那么可以具体分这几步来解决:
- 没有
focus
的时候采用fixed
固定头部 - 不要让用户进行缩放
- 当输入框
focus
时,采用绝对定位头部,同时使用window.pageYOffset
来计算滑动的距离,设置头部的top
值 - 滑动的时候,监听
scroll
方法,动态设置头部top
值 - 失去焦点的时候,重新将头部恢复至
fixed
定位 - 滑动时,如果头部结构太复杂,可能会引起固定不流畅(会跟着滚动)
代码请往这里看:
var isFocused, focusedResizing, ticking = false;
window.tryfix = function() {
var inputs = document.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++) {
input = inputs[i];
input.onfocus = focused;
input.onblur = blured;
}
window.onscroll = onScroll;
}
function focused(event) {
isFocused = true;
scrolled();
}
function blured(event) {
isFocused = false;
var headStyle = document.getElementById('header').style;
var footStyle = document.getElementById('footer').style;
if (focusedResizing) {
focusedResizing = false;
headStyle.position = 'fixed';
headStyle.top = 0;
footStyle.display = 'block';
}
}
function onScroll() {
if (!ticking) {
requestAnimationFrame(scrolled);
ticking = true;
}
}
function scrolled() {
var headStyle = document.getElementById('header').style;
var foot = document.getElementById('footer');
var footStyle = foot.style;
if (isFocused) {
if (!focusedResizing) {
focusedResizing = true;
headStyle.position = 'absolute';
footStyle.display = 'none';
}
headStyle.top = window.pageYOffset + 'px';
// window.innerHeight wrong
//var footTop = window.pageYOffset + window.innerHeight - foot.offsetHeight;
//footStyle.bottom = (document.body.offsetHeight - footTop) + 'px';
}
ticking = false;
}
tryfix();
另外如果页面缩放,也会引起头部定位不正常。详情可以看这里,关于anroid
上fixed
的支持情况,可以看这里
5. Android弹出的键盘遮住输入框
5.1 出现场景
当输入框比较靠下时,android
上弹出键盘,会将输入框遮住。
说明:测试了很多机型,发现现在的android
上的浏览器都貌似修复了这个问题,就是当键盘弹上来的时候,会默认地将输入框上移。但是我在项目中内嵌的webview
中确实遇到了这种问题。
测试说明:测试的机型包括了现在一些主要的浏览器:chrome
、UC
、QQ
、Opera
、360
、百度、猎豹,测试的android
版本包括4.1、4.4、5.1等,测试的浏览器版本都有下载最低的历史版本来测。但是就测试的情况来看,除了猎豹浏览器会出现上述的情况之外,其他的基本表现正常。(更多测试量没做,没有这么多机器呀。尴尬
移动webapp的那些bug的更多相关文章
- SharePoint 2010 搜索结果没有显示部分文件
Why SharePoint 2010 search does not show some results? SharePoint 2010 search is better than ever ...
- Cordova webapp实战开发:(7)如何通过简单的方法做到,不重新发布APP来修复bug、增加功能、或者躲开苹果的一些严格审核?
到<Cordova webapp实战开发:(6)如何写一个iOS下获取APP版本号的插件?>为止,我们已经大体学会了如何使用Cordova了,那些都是使用Cordova的开发者必备的技能. ...
- web.xml配置bug之提示The content of element type "web-app" must match "(icon?,display- name?,description?,distributable?,
错误:配置web.xml时,出现红色叉叉,提示 The content of element type "web-app" must match "(icon?,disp ...
- ios7 webapp touch bug
// ios7 touchstart bug if(navigator.userAgent.indexOf("iPhone OS 7") != -1){ var startX = ...
- Yeoman 官网教学案例:使用 Yeoman 构建 WebApp
STEP 1:设置开发环境 与yeoman的所有交互都是通过命令行.Mac系统使用terminal.app,Linux系统使用shell,windows系统可以使用cmder/PowerShell/c ...
- 【blade利刃出鞘】一起进入移动端webapp开发吧
前言 在移动浪潮袭来的时候,小钗有幸进入框架组做webapp框架开发,过程中遇到了移动端的各种坑,也产生了各种激情,就我们公司的发展历程来说 第一阶段:使用传统方式开发移动站点,少量引入HTML5元素 ...
- ipad&mobile通用webapp框架前哨战
响应式设计的意义 随着移动设备的发展,移动设备以迅猛的势头分刮着PC的占有率,ipad或者android pad的市场占有率稳步提升,所以我们的程序需要在ipad上很好的运行,对于公司来说有以下负担: ...
- maven webapp栽坑录
一.需求 如何将一个java web项目传给别人?放到github上.要想放到github上,就要学会git,markdown和maven.像那些jar包是不鼓励传到github上的,应该尽量把源文件 ...
- 2014年---移动端webapp个人年度总结
我今年是由零基础开始入门的,刚好我第一家公司入职后就马上让我接手做ipad版的专题app了.(一入门就是移动端开发,是幸运也是艰辛的开始). 我是自学前端的,当然,对Bootstrap,JQuery ...
随机推荐
- 会话跟踪Cookie与Session
会话跟踪用来跟踪用户的整个会话,常用的是Session和Cookie.Cookie通过客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份. 1.Cookie 1.1概念及使 ...
- 解决 CefSharp WPF控件不能使用输入法输入中文的问题(代码已提交到 github)
首先,本文所有 代码已经提交到github,需要的可以直接从github获取:https://github.com/starts2000/CefSharp,希望可以帮助到有需要的朋友们. CEF 简介 ...
- maven快速上手
1.maven安装 首先下载apache-maven-3.3.3-bin.zip(版本可以自己根据自己想要的下载). 解压后如下: 接下来配置系统环境变量: 到此,maven安装好了,接下来输入 ...
- Python获取股票历史、实时数据与更新到数据库
要做量化投资,数据是基础,正所谓"巧妇难为无米之炊" 在免费数据方面,各大网站的财经板块其实已提供相应的api,如新浪.雅虎.搜狐...可以通过urlopen相应格式的网址获取数据 ...
- python--DenyHttp项目(1)--调用cmd控制台命令os.system()
os.system() 参数传递cmd命令,命令执行成功返回0,失败返回1 在网上查看使用ping命令,能否Ping通 大神们有 用正则的,有用Popen() os.system()直接用返回值,简单 ...
- Java微信公众平台开发之扫码支付模式一
官方文档点击查看准备工作:已通过微信认证的公众号,必须通过ICP备案域名(否则会报支付失败)借鉴了很多大神的文章,在此先谢过了大体过程:先扫码(还没有确定实际要支付的金额),这个码是商品的二维码,再生 ...
- iOS tableview group时头尾视图间隔大小
解决: 一,当使用tableview的格式为group时 1.先设置 tableview.sectionHeaderHeight = 0.00001; tableview.sectionFooterH ...
- python学习===判断两个日期的间距天数
import datetime d1 = datetime.date(2015,10,7) d2 = datetime.date(2015,8,15) print((d1-d2).days)
- linux 两个查找工具 locate,find详解
linux 中有很多查找工具,今天主要讲解locate,find两个工具. 1.locate (1)查询系统上预建的文件索引数据库 /var/lib/mlocate/mlocate.db 注意:如果这 ...
- 局部加权回归LOWESS
1. LOWESS 用kNN做平均回归: \[ \hat{f(x)} = Ave(y_i | x_i \in N_k(x)) \] 其中,\(N_k(x)\)为距离点x最近k个点组成的邻域集合(nei ...