【解决】Android 2.x 不支持overflow、position:fixed解决方案


Android 2.x和IOS5以下都不支持overflow:auto属性(position:fixed也不支持)。


移动端浏览器兼容性和PC端相比,有过之而无不及。操作系统版本及各式浏览器和各式的屏幕大小排列组合,你永远也无法预测到你的应用会在哪部手机上冒出什么样的问题。
测试过各种浏览器(chrome手机浏览器、百度手机浏览器、手机QQ浏览器、UC浏览器、UC浏览器HD、safari浏览器、firfox手机浏览器、WinPhone系统上的各浏览器,终端包括手机、ipad及PC android模拟器、PC IOS模拟器)

其中有几个比较明显的问题:
1、一些手机对position:fixed支持不完善(跟着手势滚动后再弹回到固定位置,怀疑是否手机或是浏览器性能问题,渲染速度跟不上导致这种“卡”的效果)
2、一些手机或浏览器对overflow:auto支持不完善,在小米自带的浏览器中,对固定高度的容器设置overflow:auto后,容器内容超过容器高度后,直接被隐藏,无论怎么拖动都无法显示。特别是iframe中的overflow情况更为复杂。
3、WinPhone更为恐怖,显示效果和IE7差不多了,不支持CSS3的gradient,线性背景直接显示灰白色。
由此可见,要做到兼容各系统版本,各浏览器,各屏幕大小也着实不易。
4、基本都支持min-height属性

对于某些手机不支持overflow:auto情况,最佳解决方案就是:不去用overflow:auto属性,即不要去设置一个固定的高度。后续会讲到其它解决方案。


话说是在做APP的点击题号跳转功能时出现的这个问题,预想中的功能是这样的:点击题号列表按钮,弹出全屏题号列表(position:fixed;top:20px /*空出APP的header*/;bottom:0px;overflow;auto;),当题目很多时,就可以滑动显示题号点击跳转。测试时小米自带浏览器根本无法滑动,三星中的浏览器可以滑动部分,但显示不全。

调试方案一
于是想,既然Android和IOS高版本支持overflow属性,那就写个兼容的方法:
.box{position:absolute;top:20px /*空出APP的header*/;min-height:500px /*box需遮住整个页面*/;}
@media all and (-webkit-transform-3d){/* Android4.0下不识别该-webkit-transform-3d,使用它可做Android4.0下版本兼容 */
    .box{position:fixed;top:20px;bottom:0px;overflow;auto;min-height:0px;}
}
[注:hack来源及分析请参考:【原】webapp开发中兼容Android4.0以下版本的css hack ]
但测试效果却并不尽如人意,在Android4.x的QQ浏览器中,根本未识别这个hack,百度浏览器中成功识别,但滑动后题号还是显示不全,chrome浏览器相对支持较好。

调试方案二(1)
经过查找,德问上也有人提出这个问题,根据参考答案测试了一下

安卓2.3系统webview不支持网页的div滚动条,各位有解决方法么

android2.3的不支持滚动条,并且scrollTop也不支持的。(设置overflow未hidden就可以支持)。
给你个方法保准OK,望采纳:
    function noBarsOnTouchScreen(arg)
    {
      var elem, tx, ty;

      if('ontouchstart' in document.documentElement ) {
              if (elem = document.getElementById(arg)) {
                  elem.style.overflow = 'hidden';
                  elem.ontouchstart = ts;
                  elem.ontouchmove = tm;
              }
      }

      function ts( e )
      {
        var tch;

        if(  e.touches.length == 1 )
        {
          e.stopPropagation();
          tch = e.touches[ 0 ];
          tx = tch.pageX;
          ty = tch.pageY;
        }
      }

      function tm( e )
      {
        var tch;

        if(  e.touches.length == 1 )
        {
          e.preventDefault();
          e.stopPropagation();
          tch = e.touches[ 0 ];
          this.scrollTop +=  ty - tch.pageY;
          ty = tch.pageY;
        }
      }
    }

    调用的时候:
    noBarsOnTouchScreen(divId);

对于iframe中的容器overflow支持却并不怎么好,首先反应比较慢,其次操作控制不准,有时候滑动的iframe的滚动条,有时候又滑动容器的滚动条,每滑动一下就得卡两下(三星glaxay双核及小米,性能不是问题)。

调试方案二(2)
相同原理的应该还有如下这个方案:
[方案来源:mobile safari 下overflow:auto的解决方法 ]
function isTouchDevice(){
    try{
        document.createEvent("TouchEvent");
        return true;
    }catch(e){
        return false;
    }
}

function touchScroll(id){
    if(isTouchDevice()){ //if touch events exist...
        var el=document.getElementById(id);
        var scrollStartPos=0;

        document.getElementById(id).addEventListener("touchstart", function(event) {
            scrollStartPos=this.scrollTop+event.touches[0].pageY;
            event.preventDefault();
        },false);

        document.getElementById(id).addEventListener("touchmove", function(event) {
            this.scrollTop=scrollStartPos-event.touches[0].pageY;
            event.preventDefault();
        },false);
    }
}

最后使用touchScroll("MyElement"); 将你需要overflow:auto的元素id调用这个方法即可。


未做测试,暂保留意见,猜想和上个一样的效果,有测试过的可反馈一下。

调试方案三:
最受大家追捧的就是如下这个方案:
使用iScroll框架(http://cubiq.org/iscroll-4),iScroll可以说是解决以前提到的各种bug的一剂万能良药:

  • 区域滚动
  • 固定定位
  • 缩放(Pinch/Zoom)
  • 拉动刷新(Pull up/down to refresh)
  • 速度和性能提升
  • 精确捕捉元素
  • 自定义滚动条

使用方法参考:
Android 设备页面内 div(容器,非页面)overflow:scroll; 失效解决
iScroll框架解析——Android 设备页面内 div(容器,非页面)overflow:scroll; 失效解决
web app开发利器 - iscroll4 解决方案
【原】使用iScroll.js解决ios4下不支持position:fixed的问题


大都使用JS的解决方案都会涉及到性能问题,有些卡顿是很正常的事,毕竟浏览器的性能都参差不齐(Chrome和Firefox手机版浏览器安装文件都有23M左右,QQ、百度、UC等都只有三、五M左右,所以相比chrome和Firefox完美的性能,其它浏览器不正常才正常的。)

综上:最佳的兼容方案就是,不使用容器固定高度+overflow:auto这种结合。顺其自然,高度是多少就给它显示多少,让浏览器自己处理滑动显示的问题。


阅读本文后,您的心情是:
 
恶心
愤怒
强赞
感动
路过
无聊
雷囧
关注
知识共享许可协议
评论(4) 浏览(30766) 引用(0)
引用地址:http://blog.baiwand.com/tb.php?sc=f8d65b&id=183
Tags:
« 【经验】HTML5之Web Storage(本地存储)详解 【翻译】CSS3媒体查询(CSS3 Media Queries) »

评论列表

  1. 风过无痕 2015-04-17 17:32
    用touchmove替换,当移动元素下方页面元素多的时候,频繁的重绘导致性能极低,几乎没法用,貌似使用一些3d属性也没法触发他的gpu

    头疼中啊
     
    • 天之骄子 2015-05-07 14:50
      @风过无痕:对元素的大量操作不能在touchmove中操作呢,touchmove是手指滑动的过程中会触发的极度频繁。
       
  2. 小V 2014-08-15 17:21
    这个问题整了我两天啊
     
    • 姜一帆 2015-06-23 10:19
      @小V:想请问一下你最后是怎么解决的
       

Blogger

  • blogger
  • 天之骄子
  • 职位:研发工程师
    铭言:
    阳光与欢乐同在,
    与我同在
    主页:
    blog.baiwand.com

分类目录

日志归档

主题标签

数据统计

  • 日志:151篇
  • 评论:45条
  • 碎语:264条
  • 引用:0条

链接表

随机日志 »

最新日志 »

最新评论 »

标签云 »

订阅Rss
sitemap