上一篇介绍了iscroll4这次介绍另外一款神器.ListView组件介绍

头部(或尾部)固定,内容区域滚动,在手机APP的UI设计中已经成为一种标准,在此基础上还衍生出了下拉刷新等经典的交互设计。

而在WEB页面中,要模拟实现类似的效果非常麻烦,虽然理论上position:fixed加-webkit-overflow-scrolling:touch两个样式就可以解决,但实际开发中考虑到性能和低版本浏览器的兼容问题,仅仅使用样式并不是一个可接受的解决方案。

于是乎,诞生了不少处理滚动的JS组件,比较有代表性的如TouchScroll,iScroll等,在页面内容相对有限的情况下,使用这些组件来处理滚动效果很不错,zepto加iScroll在一段时间内也几乎成为WEBAPP开发的标准配置。

但是,当页面数据量较大时,例如某个产品分类下有数百条数据时,当然在PC端一般一定会使用分页来解决,但是由于手机APP的使用习惯,用户更喜欢不断向下滚动来加载更多数据,在这种情况下,按照传统做法,页面的DOM节点会不断增加,随之带来的效果是,闪烁,滚动动画帧数下降,甚至页面崩溃。

很容易想到,要实现数据列表的流畅滚动,首先需要限制DOM的数量。由于本人爱好电子游戏,此时想到了2D卷轴游戏中著名的Carmark scroll,其中有一个重要理念,把移出屏幕的地图tile无用部分重新渲染并拼接到移入屏幕部分,地图tile的总块数不变。把这个概念进行一下转化,和HTML页面以及DOM结合起来考虑,如果我们把每一个DOM列表项节点当作一块TILE并进行绝对定位,在页面滚动时,把消失于滚动区域的节点进行重新定位和内容填充,这样就实现了页面不停滚动,内容不断变化,DOM节点数却不会增加,这样就基本解决了传统方法遇到的问题。

结合上面的文字描述和下图就很好理解了:

1374212296_25

根据上述思路,我实现了一个简单的滚动组件。
下载地址:
http://3gimg.qq.com/cube/listView.min.js
http://3gimg.qq.com/cube/listView.js

调用方法如下:

 var list = new Cube.ListView({
    scrollBody: document.querySelector('.scroller'), //滚动容器
    template: '
<%=data.content%>
', // 列表项的模板
    itemHeight: 101, // 单个列表项的高度,暂时只支持等高的列表项,后续计划支持任意高度
    dataList: (function() {
        var arr = [], i;
        for (i = 1; i <= 1000; i ++) {
            arr.push({content:'第' + i + '项'});
        }

        return arr;
    }()) // 数据数组,JSON格式的数据,数据字段和上面模板里的标记对应
});

可以到DEMO页面测试:http://cube.qq.com/apps/listViewDemo.html

需要注意的是,由于在滚动时会进行单个列表项内部结构的频繁替换,当单个列表项DOM结构相对复杂时,会影响滚动的帧数,这里有一个优化方案是,滚动中间经过的项只进行局部填充,仅对滚动停止后最后一屏的列表项进行完整填充。

组件内部的模板函数使用的是jQuery.tmpl风格的模板语法,这里使用者可以替换成自己习惯的模板引擎或函数,对应代码在replaceTpl方法里。

同时,因为列表项DOM和数据并非一一对应,在需要绑定事件的时候,不可能对每一项一一绑定,这时使用事件代理方式来绑定事件就可以了。

组件目前已经应用于手机QQ浏览器每日精选更多页面,可以用4.3及以上版本的手机QQ浏览器访问查看效果。

本文出自Tencent Wuhan Blog

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值