本文介绍列表组件中我对滚动列表及滚动分页的实现思路。
在pc端,通过滚动进行翻页的需求非常常见;移动端也是,只不过移动端由于scroll事件触发有延迟,必须等到屏幕停止滑动后才会触发,而不是在用户的手指离开屏幕就立即触发,所以移动端最好是不用scroll事件直接做滚动翻页,而是用iscroll这类插件提供更实时的scroll事件更好。
不管是pc还是移动端,滚动翻页列表的特点都是差不多的:
1)基本上由以下几个部分组成:数据列表,顶部的加载中提示,底部的加载中提示,没有更多了,没有找到记录。正是按照这个思路,所以我把滚动列表的html结构设计成:
2)跟其它列表组件不同的是,滚动列表在请求新的数据后,有2种方式来渲染新的数据。一种是跟其它列表组件一样,直接把原来的列表内容替换;另一种是将新数据追加在原有的列表内容之后。第1种通常用于直接更改列表的查询条件时使用;第2种用于翻页查询或者刷新操作。
3)在前面的几个部分中,有两个加载中的提示,都是用来提升用户体验的东西。顶部加载提示用于条件查询,底部加载提示用于翻页查询。从它们在html中的位置也能看出来。
4)加载更多的按钮,一是防止滚动事件失效而准备的,二是有些场景可能会禁用掉滚动翻页,所以就要提供直接点击按钮的手工翻页。
5)没有更多了这个部分,在翻页查询后,根据数据结果判断没有更多的数据时显示。
6)没有找到记录的这个部分用于在列表首次查询时,如果数据为空时显示。
7)当通过滚动或者滑动操作,使得滚动列表隐藏于可视区域之下的部分不断往上滚动,并在达到某一个临界点的时候,触发翻页查询,将下一页的数据追加到数据列表后面进行显示。
针对以上的这些需求逻辑,考虑pc端和移动端的场景,我写了两个组件分别用于实现滚动列表。同时与这两个列表组件一起使用的还有另外两个分页组件,它们两两之间是配套使用的。
首先是用于实现pc端,可相对window或者某个DOM元素进行滚动分页的列表组件scrollListView以及它配套的分页组件scrollPageView组件,源码分别是:
https://github.com/liuyunzhuge/blog/blob/master/form/src/js/mod/listView/scrollListView.js
https://github.com/liuyunzhuge/blog/blob/master/form/src/js/mod/listView/scrollPageView.js
然后是用于移动端,结合iscroll一起使用的iscrollListView和iscrollPageView组件,源码分别是:
https://github.com/liuyunzhuge/blog/blob/master/form/src/js/mod/listView/iscrollListView.js
https://github.com/liuyunzhuge/blog/blob/master/form/src/js/mod/listView/iscrollPageView.js
针对以上组件有以下demo可以查看相关功能演示:
pc端相对window滚动分页demo:http://liuyunzhuge.github.io/blog/form/dist/html/listView_2.html
pc端相对某个DOM元素滚动分页demo:http://liuyunzhuge.github.io/blog/form/dist/html/listView_3.html
移动端滚动分页demo:http://liuyunzhuge.github.io/blog/form/dist/html/listView_4.html
后面的部分说明以上组件的要点。不过由于iscrollListView直接继承了scrollListView,实现非常简单;iscrollPageView的实现思路也跟scrollPageView差不多。所以后面只介绍scrollListView和scrollPageView的相关内容。
先来看scrollListView.js。
首先,代码结构还是跟前几篇博客介绍的组件都差不多,所以这里不再复述。defaults是这样定义的:
|
var DEFAULTS = $.extend({}, ListViewBase.DEFAULTS, { //列表容器的选择器 dataListSelector: '.data_list', //顶部加载中的html loadingTopHtml: '<div class="loading_top">加载中...</div>', //没有结果的html noContentHtml: '<div class="no_content">没有找到相关记录:(</div>', //底部加载中的html loadingBottomHtml: '<div class="loading_bottom">加载中...</div>', //没有更多的html noMoreHtml: '<div class="no_more">没有更多了</div>', //加载更多的html loadMoreHtml: '<a href="javascript:;" class="btn_load_more">加载更多</a>' }); |
主要是用来定义滚动列表的那几个组成部分。如果不想用默认值,那么在实例化组件的时候,传入想要设置的option就行了。
scrollListView继承了listViewBase,为了增加自己的初始化逻辑,所以用到了initMiddle这个模板方法,并在其中做了一些jq对象缓存,以及内部状态管理初始化的逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
initMiddle: function () { var opts = this.options, $element = this.$element, $data_list = this.$data_list = $element.find(opts.dataListSelector), $load_more = this.$load_more = $(opts.loadMoreHtml).appendTo($element), $no_content = $(opts.noContentHtml).appendTo($element), $loading_top = $(opts.loadingTopHtml).prependTo($element), $loading_bottom = $(opts.loadingBottomHtml).appendTo($element), $no_more = $(opts.noMoreHtml).appendTo($element); $load_more.css('display', 'block'); //状态管理:初始化完毕,顶部加载中,底部加载中,没有结果,没有更多,加载完毕 var states = this.states = { init: function () { $data_list.show(); $load_more.hide(); $no_content.hide(); $loading_top.hide(); $loading_bottom.hide(); $no_more.hide(); ͳ触发,所以移动端最好是不用scroll事件直接做滚动翻页,而是用iscroll这类插件提供更实时的scroll事件更好。
不管是pc还是移动端,滚动翻页列表的特点都是差不多的:
1)基本上由以下几个部分组成:数据列表,顶部的加载中提示,底部的加载中提示,没有更多了,没有找到记录。正是按照这个思路,所以我把滚动列表的html结构设计成:
2)跟其它列表组件不同的是,滚动列表在请求新的数据后,有2种方式来渲染新的数据。一种是跟其它列表组件一样,直接把原来的列表内容替换;另一种是将新数据追加在原有的列表内容之后。第1种通常用于直接更改列表的查询条件时使用;第2种用于翻页查询或者刷新操作。
3)在前面的几个部分中,有两个加载中的提示,都是用来提升用户体验的东西。顶部加载提示用于条件查询,底部加载提示用于翻页查询。从它们在html中的位置也能看出来。
4)加载更多的按钮,一是防止滚动事件失效而准备的,二是有些场景可能会禁用掉滚动翻页,所以就要提供直接点击按钮的手工翻页。
5)没有更多了这个部分,在翻页查询后,根据数据结果判断没有更多的数据时显示。
6)没有找到记录的这个部分用于在列表首次查询时,如果数据为空时显示。
7)当通过滚动或者滑动操作,使得滚动列表隐藏于可视区域之下的部分不断往上滚动,并在达到某一个临界点的时候,触发翻页查询,将下一页的数据追加到数据列表后面进行显示。
针对以上的这些需求逻辑,考虑pc端和移动端的场景,我写了两个组件分别用于实现滚动列表。同时与这两个列表组件一起使用的还有另外两个分页组件,它们两两之间是配套使用的。
首先是用于实现pc端,可相对window或者某个DOM元素进行滚动分页的列表组件scrollListView以及它配套的分页组件scrollPageView组件,源码分别是:
https://github.com/liuyunzhuge/blog/blob/master/form/src/js/mod/listView/scrollListView.js
https://github.com/liuyunzhuge/blog/blob/master/form/src/js/mod/listView/scrollPageView.js
然后是用于移动端,结合iscroll一起使用的iscrollListView和iscrollPageView组件,源码分别是:
https://github.com/liuyunzhuge/blog/blob/master/form/src/js/mod/listView/iscrollListView.js
https://github.com/liuyunzhuge/blog/blob/master/form/src/js/mod/listView/iscrollPageView.js
针对以上组件有以下demo可以查看相关功能演示:
pc端相对window滚动分页demo:http://liuyunzhuge.github.io/blog/form/dist/html/listView_2.html
pc端相对某个DOM元素滚动分页demo:http://liuyunzhuge.github.io/blog/form/dist/html/listView_3.html
移动端滚动分页demo:http://liuyunzhuge.github.io/blog/form/dist/html/listView_4.html
后面的部分说明以上组件的要点。不过由于iscrollListView直接继承了scrollListView,实现非常简单;iscrollPageView的实现思路也跟scrollPageView差不多。所以后面只介绍scrollListView和scrollPageView的相关内容。
先来看scrollListView.js。
首先,代码结构还是跟前几篇博客介绍的组件都差不多,所以这里不再复述。defaults是这样定义的:
|
var DEFAULTS = $.extend({}, ListViewBase.DEFAULTS, { //列表容器的选择器 dataListSelector: '.data_list', //顶部加载中的html loadingTopHtml: '<div class="loading_top">加载中...</div>', //没有结果的html noContentHtml: '<div class="no_content">没有找到相关记录:(</div>', //底部加载中的html loadingBottomHtml: '<div class="loading_bottom">加载中...</div>', //没有更多的html noMoreHtml: '<div class="no_more">没有更多了</div>', //加载更多的html loadMoreHtml: '<a href="javascript:;" class="btn_load_more">加载更多</a>' }); |
主要是用来定义滚动列表的那几个组成部分。如果不想用默认值,那么在实例化组件的时候,传入想要设置的option就行了。
scrollListView继承了listViewBase,为了增加自己的初始化逻辑,所以用到了initMiddle这个模板方法,并在其中做了一些jq对象缓存,以及内部状态管理初始化的逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
initMiddle: function () { var opts = this.options, $element = this.$element, $data_list = this.$data_list = $element.find(opts.dataListSelector), $load_more = this.$load_more = $(opts.loadMoreHtml).appendTo($element), $no_content = $(opts.noContentHtml).appendTo($element), $loading_top = $(opts.loadingTopHtml).prependTo($element), $loading_bottom = $(opts.loadingBottomHtml).appendTo($element), $no_more = $(opts.noMoreHtml).appendTo($element); $load_more.css('display', 'block'); //状态管理:初始化完毕,顶部加载中,底部加载中,没有结果,没有更多,加载完毕 var states = this.states = { init: function () { $data_list.show(); $load_more.hide(); $no_content.hide(); $loading_top.hide(); | |