【原】使用iScroll.js解决ios4下不支持position:fixed的问题

一直折腾position:fixed在ios和android的使用,而事实上这么上流的ios4系统居然不支持position:fixed,幸运的是苹果公司在ios5系统修复了这个bug,比较理想的解决方案是让所有用户把系统升级到ios5及以上版本,这种想法在国外还好,在国内环境下,因为越狱而不想去升级手机的人很多,如果强迫用户去升级,那可能会把你的产品KS了。而你也不可能跟你老板说ios4什么不兼容那个属性啊,让用户升级啊!老板看到的是结果,你做不出来,别人怎么做得出来呢,这样你老板可能会对你的能力感到怀疑,或者认为你并不专业......那其实回到头来我们还是乖乖去做好兼容,要么就找到完美的解决方案,谁让可爱的用户和亲爱的老板是上帝呢,于是,我们沦落为苦逼的攻城狮~

ios3.2~4.3不支持position:fixed截图如下,测试地址:http://caniuse.com/#search=position%3Afixed

今天的例子在这里了,如下图我们可以看到,想在手机中实现如下的布局:顶部绿色导航始终固定在屏幕上方可视区域,低部绿色导航始终固定在屏幕下方可视区域,中间灰色区域模块始终固定,模块内容超出灰色区域时可以上下拖动,如下图:

用固定定位的方法:position:fixed

HTML:

<header class="head">顶部固定区域</header>

<article class="main">
<p>当内容欲出隐藏时,灰色区域可上下拖动</p>
<p>当内容欲出隐藏时,灰色区域可上下拖动</p>
<p>当内容欲出隐藏时,灰色区域可上下拖动</p>
<p>当内容欲出隐藏时,灰色区域可上下拖动</p>
<p>当内容欲出隐藏时,灰色区域可上下拖动</p>
<p>当内容欲出隐藏时,灰色区域可上下拖动</p>
<p>当内容欲出隐藏时,灰色区域可上下拖动</p>
<p>当内容欲出隐藏时,灰色区域可上下拖动</p>
<p>当内容欲出隐藏时,灰色区域可上下拖动</p>
<p>当内容欲出隐藏时,灰色区域可上下拖动</p>
<p>当内容欲出隐藏时,灰色区域可上下拖动</p>
......
</article>

<footer class="foot">底部固定区域</footer>

CSS:

.head,.foot{position:fixed;left:0;height:38px;line-height:38px;width:100%;background-color:#99CC00;}
.head{top:0;}
.foot{bottom:0;}
.main{position:fixed;top:38px;bottom:38px;width:100%;overflow:scroll;background-color:#BABABA;}

测试地址:http://jsbin.com/aceyub/2,在手机中使用webkit内核的浏览器打开,正常显示效果如下:

而在ios4系统中,当拖动灰色区域内容时,底部绿色固定区域被挤到可视屏幕外

虽然自己是写前端CSS方向,但偶尔了解js的对自己的开发效率提升和与js的合作中是有很大帮助的,一直折腾position:fixed在ios和android的使用,还写了css的兼容方案,这次尝试用强大的iScroll.js。

iScroll

稳定版本:iScroll4.js - 2012.07.14 - V4.2

最新版本:iScroll5.js - 2013.06.03 - V5 beta 1

文件大小:34K(YUI压缩后26K,不用太担心iScroll4体积大的问题)

系统兼容性: iphone/itouch> = 3.1.1,iPad> = 3.2,Android> = 1.6,火狐,Opera桌面/手机桌面的Webkit

官方简述

iScroll 4 这个版本完全重写了iScroll这个框架的原始代码。这个项目的产生完全是因为移动版webkit浏览器(诸如iPhone,iPad,Android这些系统上广泛使用)提供了一种本地化的方式来对一个限定了高度和宽度的元素的内容进行滑动。很不幸的是,这种情况下所有的web应用的页面就不能够包含具有position:absolute的头、页尾或者是一个内容可滚动的中间区域。

然而,Android系统最新修订版已经可以支持这种功能了(尽管支持的力度还不是特别好),Apple公司似乎不太情愿将one-finger滑动事件运用到div元素上。

除了以前版本的iScroll的特性以外,iScroll 4还包括如下的特性:

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

 友情提示:iScroll 4并不是iScroll 3的简易替代版本,API文档已经不一样了。同时考虑到此版本正处于测试期,一些API可能会有细微的变化。

官方使用指南

在此文档中你会发现很多例子来教会你如何快速上手iScroll脚本库。参看文中的demo小例子并仔细阅读此文档,可能有点小无聊,但是这篇文章中却是iScroll这个脚本库的精髓之所在哦。

iScroll需要对所要进行滚动的元素进行初始化,并且不限定一个页面中使用iScroll的元素的个数(这里不考虑您的硬件配置)。滚动元素中内容的类型和长度在一定程度上将会影响iScroll脚本库里可以同时使用的元素的个数。

使用iScroll这个脚本库时,DOM树的结构要足够简单,移除不必要的标签,尽量避免过多的标签嵌套使用。

最优的使用iScroll的结构如下所示:

<div id="wrapper">
        <ul>
               <li></li>

               .....
        </ul>
</div>

在这个小例子中,ul标签将会被滚动。iScroll一定要与滚动内容外面的wrapper进行联系才会产生效果。

【注意事项】:

只有wrapper里的第一个子元素才可以滚动,如果你想要更多的元素可以滚动,那么你可以试试下面的这种写法:

<div id="wrapper">
        <div id="scroller">
               <ul>
                    <li></li>
                     ...
                </ul>
                <ul>
                     <li></li>
                      ...
                </ul>
       </div>
</div>

在这个例子中,scroller这个元素可以滚动,即便它包含两个ul元素

iScroll必须在调用之前实例化,你可以在下面几种情况下对iScroll进行实例化:

  • onDOMContentLoaded
  • onLoad
  • 以内联inline方式

下面我们逐个来讲讲这三种用法的优缺点
ONDOMContentLoaded
适用于滚动内容只包含文字、图片,并且所有的图片都有固定的尺寸
使用方法:(在head标签中添加如下代码)

<script src="iscroll.js"></script>
<script>
var myscroll;
function loaded(){
myscroll=new iScroll("wrapper");
}
window.addEventListener("DOMContentLoaded",loaded,false);
</script>

注意:myscroll这个变量是全局的,因此你可以在任何地方调用它的函数
onLoad
有些时候在DOMContentLoaded的状态下就初始化iScroll其实是有点草率的,因此此时页面的资源可能还没有全部加载
完毕。如果你遇到了一些很怪异的行为可以试试下面的写法:

<script src="iscroll.js"><script>
<script>
var myscroll;
function loaded(){
setTimeout(function(){
myscroll=new iScroll("wrapper");
},100 );
}
window.addEventListener("load",loaded,false);
</script>

这种情况下iScroll会在页面资源(包括图片)加载完毕100ms之后得到初始化,这应该是一种比较安全的调用iScroll的方式。
inline初始化
这种情况会在页面加载到js的时候就进行调用,此方法不推荐使用,但是很多javascript的大牛都在用这种方式

<script src="iscroll.js"></script>
<div id="wrapper">
<ul>
<li></li>
...
</ul>
</div>
<script>
var myscroll=new iScroll("wrapper");
</script>

不过建议你使用一些框架的ready方法来安全调用iScroll(比如jquery里的ready())

以上一点iScroll4.js简述和用法,来至百度百科的翻译,iScroll4.js还有很多使用的方法如水平推动、定义滚动条等,详细可查看ISCROLL4 简述官方地址:http://cubiq.org/iscroll-4

那么,对于我的问题,使用简单的ONDOMContentLoaded实现,默认即是竖直拖动,代码如下:

 HTML:

<header class="head">顶部固定区域</header>
<article class="main" id="wrapper"> 这里id为wrapper iscroll里面定义好的 --> <div><!-- 可滚动区域 --> <p>当内容欲出隐藏时,灰色区域可上下拖动</p> <p>当内容欲出隐藏时,灰色区域可上下拖动</p> <p>当内容欲出隐藏时,灰色区域可上下拖动</p> <p>当内容欲出隐藏时,灰色区域可上下拖动</p> <p>当内容欲出隐藏时,灰色区域可上下拖动</p> <p>当内容欲出隐藏时,灰色区域可上下拖动</p> <p>当内容欲出隐藏时,灰色区域可上下拖动</p> <p>当内容欲出隐藏时,灰色区域可上下拖动</p> <p>当内容欲出隐藏时,灰色区域可上下拖动</p> <p>当内容欲出隐藏时,灰色区域可上下拖动</p> <p>当内容欲出隐藏时,灰色区域可上下拖动</p> ...... </div> </article> <footer class="foot">底部固定区域</footer>

css:

:root ,body{height:100%;}/* 定义页面内容为一屏展现 这2个标签都必须设置高度100%  */
body{display:-webkit-box;display:box;-webkit-box-orient:vertical;}/* 定义页面为弹性盒子模型 内容垂直布局  */
.head,.foot{height:38px;line-height:38px;width:100%;background-color:#99CC00;}
.main{width:100%;background-color:#BABABA;-webkit-box-flex:1;box-flex:1;overflow:hidden;}/* 定义该模块的高度自动适应 占据页面(除头部和顶部)剩下的高度  */

javascript:

<script type="text/javascript" src="iscroll.js"></script>
 <script>
     var myscroll;
    function loaded(){
               myscroll=new iScroll("wrapper");
     }
   window.addEventListener("DOMContentLoaded",loaded,false);
</script>

这就是完美的解决方案啦,测试地址:http://jsbin.com/aceyub/7,支持ios4和android系统等,把这个地址丢入你的手机试试看吧!

iScroll.js对webapp开发来说是非常有使用价值,感谢CUBIQ.ORG,而iScroll5.js已经开始测试,期待下一个强大的版本~

posted @ 2013-06-14 15:21 白树 阅读(...) 评论(...) 编辑 收藏