bug持续更新中...

测试浏览器

Chrome: 61.0.3163.73

Safari: 10.0(IOS 10.3.3)

Github: webapp-bugs

1. IOS overflow: scroll 全屏滚动出界

1.1 出现场景

滑动到最顶部(最底部)的时候,停下,然后继续向上滑动(向下滑动)

1.2 解决方案

  • 手动设置滑到边界时的scrollTopscrollFix

当快滑到上边界或者下边界的值时,手动设置scrollTop与达到边界时相差一像素(上边界时:scrollTop = 1, 下边界时:scrollTop = elem.scrollHeight - elem.offsetHeight - 1),这样就不会触发出界的极限条件。

具体实现:

  1. var ScrollFix = function(elem) {
  2. // Variables to track inputs
  3. var startY, startTopScroll;
  4. elem = elem || document.querySelector(elem);
  5. // If there is no element, then do nothing
  6. if(!elem)
  7. return;
  8. // Handle the start of interactions
  9. elem.addEventListener('touchstart', function(event){
  10. startY = event.touches[0].pageY;
  11. startTopScroll = elem.scrollTop;
  12. if(startTopScroll <= 0)
  13. elem.scrollTop = 1;
  14. if(startTopScroll + elem.offsetHeight >= elem.scrollHeight)
  15. elem.scrollTop = elem.scrollHeight - elem.offsetHeight - 1;
  16. }, false);
  17. };

注:1. 这个方法只能部分防止,在某些时候还是会触发出界。2. 有说在全局滚动下和局部滚动下会有差异,但是就我测试的情况来说,差异并不是特别大。可能是版本太高的原因,具体结论还待测试更多机型。

  • 头部由static变为fixed(测试效果貌似更好)
  1. .toolbar {
  2. -webkit-box-sizing: border-box;
  3. padding: 1em;
  4. background: #222;
  5. color: #fff;
  6. font-weight: bold;
  7. text-align: center;
  8. height: 50px;
  9. /* 添加fixed头部 */
  10. position: fixed;
  11. top: 0;
  12. z-index: 1;
  13. width: 100%;
  14. }

2. IOS通过脚本使输入框聚焦,无法弹出键盘

2.1 出现场景

看如下代码:

  1. // html
  2. <input type="email" class="form-control" id="inputEmail3" placeholder="Email">
  3. <button id="submitBtn" class="btn btn-default">Sign in</button>
  4. // script
  5. var inputEmail3 = document.querySelector('#inputEmail3');
  6. var submitBtn = document.querySelector('#submitBtn');
  7. // way1
  8. setTimeout(() => {
  9. inputEmail3.focus();
  10. }, 2000);

这种方式下:在IOS上输入框聚焦确没有办法弹出键盘

2.2 解决方案

爬墙爬到这么一个issue,3楼eddiemonge老哥说到了,在IOS下除非用户手动触发了输入框的focus事件,才会触发键盘,至于设置定时器也是不管用的;但是,手动点击一个按钮,在按钮的操作中再来执行focus事件倒是管用的。他还给出了一个http://jsbin.com/inunis/8/edit?html,js,output

  1. // 这样是可以弹出键盘的
  2. submitBtn.onclick = function(e) {
  3. e.preventDefault();
  4. inputEmail3.focus();
  5. }

3. IOS光标不跟随输入框移动

3.1 艰辛历程

我为什么会关注这个问题:那是因为我**(这里省略一万个草泥马)也遇到了这个问题呀,容我细细说来。

我有一个登录页面,在聚焦之后需要往上弹一下,android上正常,然后IOS上还同时引出了一个BUG:输入框上去了,但是光标却在下面闪。怎么办呢?当然是靠想办法解决呀,后来我就想在输入框上贴一层蒙版,点击了之后消失,同时在点击操作中,等到动画结束之后再执行输入框的focus,行不行呢?好期待。。。

html代码是这样的:

  1. // ... 这里省略若干
  2. <div class="col-sm-10">
  3. <input type="email" class="form-control" id="inputEmail3" placeholder="Email" />
  4. <div class="input-overlay" id="overlay"></div>
  5. </div>

样式:

  1. .input-overlay {
  2. position: absolute;
  3. top: 0;
  4. left: 0;
  5. width: 100%;
  6. height: 100%;
  7. background-color: rgba(255, 0, 0, 0.3);
  8. z-index: 2;
  9. }

脚本:

  1. overlay.addEventListener('touchstart', function(e) {
  2. e.preventDefault();
  3. testForm.style.transform = 'translate3d(0, 0, 0)';
  4. overlay.style.display = 'none';
  5. overlay.style.zIndex = -1;
  6. setTimeout(function() {
  7. inputEmail3.focus();
  8. }, 200);
  9. });

正所谓想象是好样的,但是实际行使起来却不是那么令人满意。是的,毫无效果。后来我想,是不是可以模拟一个事件,再触发一次点击,然后代码是这样的:

  1. function mockEvent(fn) {
  2. var createDiv = document.createElement('div');
  3. createDiv.style.display = 'none';
  4. document.body.appendChild(createDiv);
  5. // 未做兼容
  6. var e = document.createEvent('MouseEvent');
  7. e.initEvent('xx', true, true);
  8. createDiv.addEventListener('xx', function() {
  9. fn && fn();
  10. createDiv.remove();
  11. });
  12. createDiv.dispatchEvent(e);
  13. }
  14. overlay.addEventListener('click', function(e) {
  15. // ...
  16. setTimeout(function() {
  17. mockEvent(function() {
  18. inputEmail3.focus();
  19. });
  20. }, 200);
  21. });

答案依然是:不行。然后我想,是不是setTimeout的原因,只要存在延迟的情况下就不行。结果我去这么试了一下,将之前的按钮直接点击方式改为200ms之后执行focus

  1. submitBtn.onclick = function(e) {
  2. e.preventDefault();
  3. setTimeout(function() {
  4. inputEmail3.focus();
  5. }, 200);
  6. }

果然,只要设置延迟就不起效果了。顿时突然想到移动端点透事件貌似有个300ms延迟执行。虽然点透事件在移动端会被处理掉,然而我只是想验证一下我的猜想。然后我又这么写:

  1. // html
  2. <div class="col-sm-10">
  3. <input type="email" class="form-control" id="inputEmail3" placeholder="Email" />
  4. <div class="input-overlay" id="overlay"></div>
  5. <a class="input-link" href="javascript:;" id="link">link</a>
  6. </div>

overlay下面放一个link,然后在overlay上绑定touchstart事件,在link上绑定click事件。这样在上层的遮罩去掉之后,就可以300ms后执行下面的link层中的事情,那么也算是用户真正地触发的点击行为,美滋滋。结果我在代码中加了这个东西:

  1. overlay.addEventListener('touchstart', function(e) {
  2. // ...
  3. });
  4. link.addEventListener('click', function() {
  5. link.style.display = 'none';
  6. link.style.zIndex = -1;
  7. inputEmail3.focus();
  8. });

尼玛呀,还是不行,绝望了。

然而。。。

天生不死心,又去爬墙呀。输入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:

  1. input {
  2. text-shadow: rgba(0,0,0,0) 0px 0px 0px;
  3. }
  4. input.force-redraw {
  5. text-shadow: none;
  6. }

JS:

  1. myScroll = new iScroll('wrapper', {
  2. onScrollMove: function() {
  3. $('input').toggleClass('force-redraw');
  4. }
  5. });

是的,有木有很激动。于是我这样写:

  1. // css
  2. input {
  3. text-shadow: rgba(0,0,0,0) 0px 0px 0px;
  4. }
  5. input.force-redraw {
  6. text-shadow: none;
  7. }
  8. // javascript
  9. inputEmail3.addEventListener('focus', function() {
  10. testForm.style.transform = 'translate3d(0, 0, 0)';
  11. setTimeout(() => {
  12. inputEmail3.className = 'form-control force-redraw';
  13. }, 300);
  14. });

效果大体上实现了,但是仍然有瑕疵。就是必须设置延迟300ms以上,不然,光标重绘不正常,而且光标有明显的移动过程。所以如果童鞋们如果发现有什么更好的办法,还望不吝赐教。

另外,如果一个页面中有输入框,聚焦之后,滑动过程中在IOS上可能会出现不流畅的问题,其实可以这么做:监测页面的touchmove事件,如果当前页面存在着输入框被active,那么直接让其blur,保证滑动过程中没有输入框被聚焦。(不过以我的测试情况来看,在chromesafari上滑动的时候输入框不再被激活,类似在PC端滑动的时候采用了蒙版或者points-event: none;的效果)

  1. var thisFocus;
  2. var content = document.querySelector('#content');
  3. var inputs = document.getElementsByTagName('input');
  4. for (var i = 0; i < inputs.length; i++) {
  5. var input = inputs[i];
  6. input.onfocus = focused;
  7. }
  8. function focused(e) {
  9. thisFocus = e.target;
  10. }
  11. content.addEventListener('touchmove', function() {
  12. if (thisFocus) {
  13. thisFocus.blur();
  14. thisFocus = null;
  15. }
  16. });

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定位
  • 滑动时,如果头部结构太复杂,可能会引起固定不流畅(会跟着滚动)

代码请往这里看:

  1. var isFocused, focusedResizing, ticking = false;
  2. window.tryfix = function() {
  3. var inputs = document.getElementsByTagName('input');
  4. for (var i = 0; i < inputs.length; i++) {
  5. input = inputs[i];
  6. input.onfocus = focused;
  7. input.onblur = blured;
  8. }
  9. window.onscroll = onScroll;
  10. }
  11. function focused(event) {
  12. isFocused = true;
  13. scrolled();
  14. }
  15. function blured(event) {
  16. isFocused = false;
  17. var headStyle = document.getElementById('header').style;
  18. var footStyle = document.getElementById('footer').style;
  19. if (focusedResizing) {
  20. focusedResizing = false;
  21. headStyle.position = 'fixed';
  22. headStyle.top = 0;
  23. footStyle.display = 'block';
  24. }
  25. }
  26. function onScroll() {
  27. if (!ticking) {
  28. requestAnimationFrame(scrolled);
  29. ticking = true;
  30. }
  31. }
  32. function scrolled() {
  33. var headStyle = document.getElementById('header').style;
  34. var foot = document.getElementById('footer');
  35. var footStyle = foot.style;
  36. if (isFocused) {
  37. if (!focusedResizing) {
  38. focusedResizing = true;
  39. headStyle.position = 'absolute';
  40. footStyle.display = 'none';
  41. }
  42. headStyle.top = window.pageYOffset + 'px';
  43. // window.innerHeight wrong
  44. //var footTop = window.pageYOffset + window.innerHeight - foot.offsetHeight;
  45. //footStyle.bottom = (document.body.offsetHeight - footTop) + 'px';
  46. }
  47. ticking = false;
  48. }
  49. tryfix();

另外如果页面缩放,也会引起头部定位不正常。详情可以看这里,关于anroidfixed的支持情况,可以看这里

5. Android弹出的键盘遮住输入框

5.1 出现场景

当输入框比较靠下时,android上弹出键盘,会将输入框遮住。

说明:测试了很多机型,发现现在的android上的浏览器都貌似修复了这个问题,就是当键盘弹上来的时候,会默认地将输入框上移。但是我在项目中内嵌的webview中确实遇到了这种问题。

测试说明:测试的机型包括了现在一些主要的浏览器:chromeUCQQOpera360、百度、猎豹,测试的android版本包括4.1、4.4、5.1等,测试的浏览器版本都有下载最低的历史版本来测。但是就测试的情况来看,除了猎豹浏览器会出现上述的情况之外,其他的基本表现正常。(更多测试量没做,没有这么多机器呀。尴尬

移动webapp的那些令你头疼的事的更多相关文章

  1. 令新手头疼的modelsim库编译

    估计很多人买了CB哥的书来看吧,他们在学习modelsim仿真的过程中可能遇到过明明是按照书上的步骤添加器件库的了,但还是出现如下的错误: 首先,我想说的是CB哥书上的modelsim-altera1 ...

  2. C#设计模式之工厂

    IronMan之工厂 前言 实用为主,学一些用得到的技术更能在如今的社会里保命. 虽然在日常的工作中设计模式不是经常的用到,但是呢,学习它只有好处没有坏处. 设计模式像是一种“标签”,它是代码编写者思 ...

  3. 不care小米,梁军坦言微鲸才是乐视最大对手

    除了每天毫无悬念地上头条和陷入困境的生态帝国之外,乐视还要继续操心着它的对手们."挑事儿"的小米已经不足为惧,后起之秀微鲸成了一个令它"头疼"的所在.因为,不仅 ...

  4. 学习使用html与css,并尝试写php

    这两天看了一点php,本想着实践一下,发现自己的服务器还没弄好,php的代码只写了两三行嵌在html中,还运行不了,同时还发现自己这几天学的html和css还不够,总是频频出现问题,学习的样式和布局都 ...

  5. 记一次python编码错误

    摘要: 断断续续写python一段时间了,让我说python最令我头疼的问题,莫过于编码问题.最近做大论文,使用python再次出现编码报错.错误如下: "UnicodeEncodeErro ...

  6. MySQL数据库“局部”乱码

    问题:“网页显示中午”与“数据库查看中文”总有一个是乱码,或者“网页中总有部分中文乱码” 装了PHPStudy之后,用alter修改过一次数据库的编码方式为utf8!当时的网页的编码显示是正常的,所以 ...

  7. CentOs 7怎么联网

    在安装好Centos7后,网络还不能正常使用,需要我们手动配置.并且Linux的网络配置并不太容易,新手经常不知道从何开始.为了解决这个令大家头疼的问题,我在此将成功的配置过程与大家分享.希望大家都能 ...

  8. 如何在2016年成为一个更好的Node.js开发者

    本文主要讨论一些进行Node.js开发的最佳实践和建议,这些建议不仅仅适合开发者,还适合那些管理与维护Node.js基础架构的工作人员.遵循本文提供的这些建议,能够让你更好的进行日常的开发工作. St ...

  9. 【转】MIPS交叉编译环境的建立

    原文网址:http://imgtec.eetrend.com/forum/2371 我觉得对于MIPS处理起来说最令新手头疼的应该就是编译环境的建立了,这点MIPS做的确实不是很好,不像ARM那样有许 ...

随机推荐

  1. Oracle EBS SLA取值

    -- 从GL总账追溯到 => 子分类账SLA => 子模块AP.AR等 SELECT xep.name, -- 法人主体 xep.legal_entity_identifier, -- 法 ...

  2. Oracle EBS AP 供应商API

    --创建供应商地址上的电话号码 created by jenrry 20170419 DECLARE l_return_status VARCHAR2(1); l_msg_count NUMBER; ...

  3. SQL Server自动备份 备份到本地或者远程服务器

    0.1 在SQLServer2008 --> 备份数据库 --> 安全 --> 新建用户 --> 用户名 选择该windows用户 (确保 --> 机器名/人名 --&g ...

  4. 在Eclipse中运行Jboss时出现java.lang.OutOfMemoryError:PermGen space及其解决方法

    在Eclipse中运行Jboss时出现java.lang.OutOfMemoryError:PermGen space及其解决方法 在Eclipse中运行Jboss时,时间太长可能有时候会出现java ...

  5. 跨平台开发 -- C# 使用 C/C++ 生成的动态链接库

    操作环境:Visual Studio 2017 如何实现 使用 C# 进行嵌入式开发? .NET Core 虽然实现了跨平台,但是不可能处处使用 C# 开发,就好像没人使用SQL开发安卓APP,每种语 ...

  6. 内网arp攻击

    内网arp攻击 环境:一台kali虚拟机(攻击者),一台win7虚拟机(用户) 网络:NAT模式 网段:192.168.41.0/24 网关:192.168.41.2/24 win7的IP地址:192 ...

  7. [ML学习笔记] 回归分析(Regression Analysis)

    [ML学习笔记] 回归分析(Regression Analysis) 回归分析:在一系列已知自变量与因变量之间相关关系的基础上,建立变量之间的回归方程,把回归方程作为算法模型,实现对新自变量得出因变量 ...

  8. 对比flash与ajax哪个好?

    Ajax的优势: (1)可搜索性 普通的文本网页会更有利于SEO.文本内容是搜索引擎容易检索的,而繁琐的swf字节码却是搜索引擎不愿触及的.虽然Google等一些大型的搜索引擎可以检索SWF内部的内容 ...

  9. 2.2.2 RelativeLayout(相对布局)

    本节引言 在上一节中我们对LinearLayout进行了详细的解析,LinearLayout也是我们 用的比较多的一个布局,我们更多的时候更钟情于他的weight(权重)属性,等比例划分,对屏幕适配还 ...

  10. mysql中find_in_set结合GROUP_CONCAT使用

    SELECT stationid from sys_workstation where FIND_IN_SET(stationid,(SELECT GROUP_CONCAT(opera_area) f ...