虽然Android设备的性能越来越高,原生浏览器对html5和css3的支持度越来越高。但在实际开发过程当中,会发现移动版本的浏览器存在很多诡异和头痛的问题。对这些问题,有的可以采取一定方式避免,有得则是不可避免的。因此有必要将这些问题记录下来,在以后的开发中,避免陷入跟浏览器较劲的局面。

1.局部滚动

当元素被设置为overflow:auto|scroll时,Android3.0以下的原生浏览器并不支持滚动条。也就是说,并不支持局部滚动。
    好在3.0及以上版本修复了这个问题。但是,老问题没有了,新问题出现了。虽然支持局部滚动条了,但是对scrollTop属性却是无效的。这里的无效是指,设置scrollTop并不能让滚动条滚动到指定的位置,相应的,局部滚动元素,也不会响应scrollTop的值。即是说,scrollTop已经变成了一个无用的属性。也许你想到了scrollIntoView这个方法,但是很遗憾,这个方法也是起不到你想要的作用的。

    <div id="scroller" style="height: 200px;overflow-y: auto;">1<br/> 2<br/> 3<br/> 4<br/> 5<br/> 6<br/> 7<br/> 8<br/> 9<br/> 10<br/><span id="anchor_1">hahaha</span>1<br/> 12<br/> 13<br/> 14<br/> 15<br/> 16<br/> 17<br/> 18<br/> 19<br/> 20<br/></div>
    <script>var scroller = document.getElementById("scroller");var anchor = document.getElementById("anchor_1");scroller.scrollTop = 60;console.log(scroller.scrollTop);//result is: 50 anchor.scrollIntoView();console.log(scroller.scrollTop);//result is: 180</script>

可以清楚的看到,直接设置scrollTop或者调用scrollIntoView都会改变scrollTop的值。但却不会引起局部滚动。
    然而,scrollTop并非是被浏览器废弃的属性,只是在overflow:auto|scroll的情况下,失去了应有的作用而已。如果设置元素为overflow:hidden,那么你会发现,scrollTop会恢复应有的作用。这简直太奇怪了!因为overflow变为hidden之后,局部滚动就会被取消。原本成对的东西,现在变成了鱼与熊掌不可兼得。要使用浏览器内置的局部滑动效果,那就要放弃scrollTop;想要通过scrollTop随机控制滚动的位置,那么就无法使用浏览器的局部滑动效果。这简直糟糕透了。但是这并不能难倒聪明的程序员,有人想到了通过下面的方式实现“鱼与熊掌兼得”。

    <script>scroller.style.overflow = "hidden";scroller.scrollTop = 60;scroller.style.overflow = "auto";</script>

在你为自己这点小聪明偷笑的时候,严酷的现实无情地摧毁了你的期望。天啊?我已经设置overflow为hidden了,为什么还是不行!稍加尝试你就会发现。问题出在第三句
overflow = "auto" 当你这么做的时候,滚动条又回到顶部,同时scrollTop又被重置为0了。看看下面每句代码的注释就明白了。

   <script>scroller.style.overflow = "hidden";//scroller可以支持scrollTop属性了。scroller.scrollTop = 60;//scroller滚动到了距离顶部60px的位置。scroller.style.overflow = "auto";//scroller不再支持scrollTop属性了,并且滚动到了距离顶部0px的位置,scrollTop属性被重置为0。</script>

所以运行时你会发现,scroller元素在滚动了一下以后,立即恢复了原来的样子。因为很快,所以除了好像元素闪了一下子,并没有其他效果。
    至此,所有的尝试都失败了。失败并不可怕,尤其是步入绝望以后,我们便不再对它产生奢望,转而从其他角度找寻办法。
    其实最简单的办法,就是去看别人是怎么做的。我打开了淘宝的网页版阿里旺旺。查看源代码发现,淘宝的开发人员并没有跟各种浏览器纠结。而是转而使用了iscroll.js效果组件。js效果从来不是最优的选择,尤其是在原生效果内置存在的情况下。但目前的情况是,大部分移动触屏设备对局部滚动的效果支持不良,而且样式和效果不统一。这个时候,使用js或许是无奈,但却是最佳的选择。

结论:考虑目前市面上移动设备对overflow:auto|scroll支持较差。建议使用js方式模拟替代浏览器内置的滚动效果。缺点是性能比原生滚动差。

2014/1/14:如果可以考虑整屏滚动的话,就可以不用设置body的height。这样,浏览器自己的控制滚动就可以了。同时也不会影响scrollTop,scrollIntoView等的使用。

2.浏览器系统条对scrollTop计算的影响

在桌面浏览器中,系统条是不包含在客户显示区中的。所以通常它的大小不会对scrollTop的计算产生影响。
此时,如果我们有一个元素(element)在滚动区域之外,我们想通过设置容器(container)的scrollTop来模拟element.scrollIntoView(false)滚动到屏幕低端。可以
container.scrollTop = $(element).offset().top - window.innerHeight + element.offsetHeight;
即 容器的滚动距离 = 元素距页面顶端的距离 - 客户区高度 + 元素自身高度
但是移动版本浏览器中。由于客户区可视区域较小,浏览器厂商通经常通过适时的隐藏系统条以达到节省屏幕空间的效果。
在Android原生浏览器中,系统条会随着屏幕的滚动移出屏幕外。因此,客户区会变大。上面的计算公式就不适用了。甚至连原生浏览器自己的scrollIntoView(false)也会计算错位置。
正确的计算公式变为 容器的滚动距离 = 元素距页面顶端的距离 - 客户区高度 + 元素自身高度 - 系统条高度
但这只是Android Stock Browser的情况。像Chrome mobile跟桌面版是一致的,因为它的滚动条是固定占据一定空间的。
此外,window.innerHeight、document.documentElement.clientHeight、window.screen.availHeight等关于确定区域大小的参数值,在不同的浏览器下,取值有很大差距,有时候取值为逻辑像素值,有时候为真实像素值,有时候去除了android中的虚拟按键条的高度,有时候未考虑。比如,在android原生浏览器中。window.innerHeight和document.documentElement.clientHeight是一样的,但在chrome下是2:1的关系,这是因为我的设备屏幕的逻辑像素比是2:1。在Chrome浏览器下,window.screen.availHeight的高度减去了android虚拟按键区的高度,但在原生浏览器下是整个屏幕的实际分辨率高度。
结论:通过算数计算去设置scrollTop,经常会面临很多浏览器的兼容性问题,而且通过设置scrollTop自动滚动区域的需求,很多时候并非是必须的。如果我们可以通过锚点解决,就尽量不要通过数学计算的方式。在android原生浏览器下,就连scrollIntoView(false)也会移错位置(scrollIntoView(true)不会出错,原因结合上面的讲解理解一下吧),但错位只是相差了一个系统条的距离,有时候这种偏差是可以接受的,毕竟在其他设备的浏览器中,这种实现是没有问题的。

3.长连接与setInterval

标题看起来好像是八竿子打不着的两个东西。但却是实实在在存在的问题。我在做一个即时通信的wapim app时候,发现的这个问题。说一下背景。wapim页面初始化方法中,会通过jsonp的方式与c++实现的服务器建立起长连接,以便接收新消息。同时,页面加载时会立即发送一个ajax请求,获取用户的未读消息数,如果有未读消息,就会通过setInterval方法不间断的闪动一个“信封”图案的小元素对用户进行提示,告知用户有新消息到来。但问题由此而来,长连接有时会导致android浏览器的加载进度条阻塞(至于这里我为什么会用“有时”,是因为有时候长连接不会阻塞加载进度条)。在进度条出现时,信封图标只会闪一次。之后就再也不会出现了。但通过调试,发现其实setInterval是按部就班地隔段执行的。原因出在对display属性的操作上。如果通过display属性控制元素的隐藏与显示,则元素只会显示一次,隐藏之后就无法再次显示了。但有意思的是,如果此时触摸屏幕,则元素又会显示一次,然后又隐藏不会再显示了。此外,如果点击“停止”按钮,强制断开连接,进度条消失,则闪动又恢复正常。
    到现在为止,问题的产生原因很不明确。需要进一步测试。我将元素隐藏与显示的控制属性改用style.visibility。结果发现以上问题消失了。
    大家都知道,display属性会触发layout update。而visibility不会。因此,进一步大胆推测,所有会触发layout update的style属性都不可重复执行。元素的setInterval改用float以left和right交替,发现问题重现了,从而印证了自己的想法。
结论:setInterval方法中,尽量不要交替改变会触发layout update的style属性。

Android Stock Browser Web App开发当中遇到的问题(持续更新)相关推荐

  1. web系统 手机app 能访问吗?_成都APP开发:原生APP开发与Web APP开发有什么区别呢?...

    智能手机上的APP应用软件对于人们来说已经成为日常工作生活当中必不可少的工具,无论是工作生活中的聊天交流,购物,饮食,出行,娱乐都会有相应的APP软件.目前常见的APP软件开发模式有两种,一种是原生A ...

  2. 原生开发什么意思_成都APP开发:原生APP开发与Web APP开发有什么区别呢?

    智能手机上的APP应用软件对于人们来说已经成为日常工作生活当中必不可少的工具,无论是工作生活中的聊天交流,购物,饮食,出行,娱乐都会有相应的APP软件.目前常见的APP软件开发模式有两种,一种是原生A ...

  3. Cordova跨平台Web App开发指南(安卓篇)

    Cordova跨平台Web App开发指南(安卓篇) 打包ios包必须用苹果系统,没钱买IOS设备,这里只介绍Android平台打包 一.Cordova简介' 在进行Cordova开发之前, 先花点时 ...

  4. web app开发技巧总结

    Web APP开发技巧总结 一.META/LINK相关: 1.百度禁止转码 通过百度手机打开网页时,百度可能会对你的网页进行转码,往你页面贴上它的广告,非常之恶心.不过我们可以通过这个meta标签来禁 ...

  5. 原生APP开发与WEB APP开发的区别

    APP开发模式通常分为Web APP与Native APP原生模式两种,这两种模式均各自有自己的优势,到底是采用Native App开发还是采用Web App开发一直是业界争论的焦点,但是随着HTML ...

  6. 【知识整理】聊聊web app开发的那些事

    一.什么是web app? 根据本人理解,通俗点讲,web app是用前端的HTML5.CSS3.JavaScript借助于适当的web app开发SDK或平台整合开发,可以编译为兼容大多数Andro ...

  7. app开发和web开发_理解现代Web App开发概念的指南

    app开发和web开发 Millions of businesses exchange information on the internet and to interact with their t ...

  8. Web App开发技巧

    webApp和nativeApp的区别 Native App 开发成本非常大.一般使用的开发语言为JAVA.C++.Objective-C. 更新体验较差.同时也比较麻烦.每一次发布新的版本,都需要做 ...

  9. Web APP开发和原生app开发优势及区别

    原生app开发优势: Native App就是原生App的意思,所以原生App开发也就是指基于本地智能操作系统的App开发服务.原生App实际上是一种基于智能手机本地操作系统如Android.IOS和 ...

最新文章

  1. 对科大讯飞的过度宽容就是对科大讯飞的伤害,从科大讯飞裁员说起
  2. 《Adobe Acrobat XI经典教程》—第6课转换PPT演示文稿
  3. CSS 实现加载动画之四-圆点旋转
  4. CodeForces - 1350E Orac and Game of Life(bfs)
  5. 多域资源整合之基础准备--DNS配置
  6. 惊呆!到2020年三大运营商5G投入将达1800亿美元
  7. 视频描述(Video Captioning)调研
  8. 未能加载虚拟光盘VBoxGuestAdditions.iso
  9. 【C 语言】文件操作 ( fseek 函数 )
  10. Python内置TCP服务器
  11. matlab中图例的字怎么改,如何在Matlab图形图例中设置自定义标记
  12. CSD-1371电力监控系统网络安全监测装置(Ⅱ 型)介绍
  13. 用户增长因果推断概念
  14. 剑指Offer 46.把数字翻译成字符串(Python)
  15. 互联网时代如何做好网络营销
  16. 单接口测试(场景测试)
  17. 【OpenCV C++】分离颜色通道多通道图像混合
  18. AbsoluteLayout布局
  19. 《vue3+ts+element-plus 后台管理系统系列》之微前端版本
  20. 电子元器件与设计库(原理图库、PCB库)的关系

热门文章

  1. 私募单周减仓创纪录 超八成股票仓位降至65%
  2. BSR:Block compressed Sparse Row matrix format
  3. R语言which函数详解以及Rcpp改写
  4. dokuwiki中文linux,linux 下面 dokuwiki安装 - Dokuwiki 中文教程
  5. C++逗号运算符运算规则
  6. Springboot居民小区物业管理系统4bq5w计算机毕业设计-课程设计-期末作业-毕设程序代做
  7. Halcon的二维码解码步骤和解码技巧
  8. 浏览器体系结构_了解代理浏览器:体系结构
  9. Windows和Linux文件系统格式
  10. Groovy 条件语句