js实现跨平台滑动加载

一、原理讲解

  1、首先,用一个有固定高度的div作为list,并将其overflow-y设置为auto或visible

  2、当滑动到底部时,在list div底部插入加载效果元素,并向服务器请求数据,请求时发送请求的页数(当前页数+1)索引与搜索关键字。

  3、服务器返回的数据可以是html、json、xml等数据,如果是html,则将其插入到list,如果是json或xml则生成html后插入到list。插入之后将当前页数+1,如果服务器返回的数据为空,则当前页数不变。不管请求是否成功,是否返回数据,都将加载效果元素从list中移除。

二、简单实现

  本实现服务端用的是ASP.NET Core,滑动加载时返回的HTML。

  1、先贴后台代码

 1         public IActionResult SlidingLoading(string kw, int pageIndex = 1)
 2         {
 3             var list = new List<string>();
 4             for (int i = 1; i <= 10; i++)
 5             {
 6                 list.Add($"第{(pageIndex - 1) * 10 + i}条数据");
 7             }
 8             //ajax加载返回列表项
 9             if (Request.Headers.ContainsKey("X-Requested-With"))
10             {
11                 if(Request.Headers["X-Requested-With"] == "XMLHttpRequest")
12                 {
13                     return View("SlidingLoading.partial", list);
14                 }
15             }
16             //否则返回主页
17             return View(list);
18         }
View Code

  2、再贴JS代码

  1 function SlidingLoading() {
  2     var _this = this;
  3     //当前搜索关键字,搜素后滑动加载时保持不变,除非重新搜索
  4     var keyword = "";
  5     //layer弹出层索引
  6     var layerIndex = 0;
  7     //记录一个值,该值为当前是否在加载中,1:加载中,0不在加载中
  8     var flagloading = 0;
  9     //加载中效果元素
 10     var $loading = $("<div>", { class: "loading" }).html("<i class=''></i><label>加载中...</label>");
 11     //空列表效果元素
 12     var $empty = $("<div>", { class: "empty" }).html("<i class=''></i><label>暂无记录</label>");
 13     // 列表jquery对象
 14     var $list;
 15     //搜索框jquery对象
 16     var $kw;
 17     var defaults = {
 18         url : "",//请求数据的url
 19         pageIndex : 0,//初始列表页数
 20         kwSelector : "#kw",//搜索框
 21         itemSelector : ".item",//列表项
 22         listSelector: ".list",//列表
 23         btnSelector: "#btn-search",//搜索按钮
 24         //生成 请求数据时发送给服务器的数据(默认返回JSON),其他请重写
 25         //获取请求页数与搜索关键字
 26         //bsearch,为true则将请求页数至为1,否则加1,重写时可根据此参数确定返回的页数
 27         //覆盖此方法时应很小心,必须返回请求的页数
 28         getJson: function (bsearch) {
 29             if (bsearch) {
 30                 return { pageIndex: 1, kw: $kw.val() };
 31             }
 32             else {
 33                 return { pageIndex: defaults.pageIndex + 1, kw: $kw.val() }
 34             }
 35         }
 36     };
 37 
 38     //获取当前的页数
 39     this.getPageIndex = function () {
 40         return pageIndex;
 41     }
 42     //获取当前搜索关键字
 43     this.getKeyword = function () {
 44         return keyword;
 45     }
 46     //初始化
 47     //options可覆盖defaults
 48     this.init = function (options) {
 49         $.extend(defaults, options);
 50         $list = $(defaults.listSelector);
 51         $kw = $(defaults.kwSelector);
 52         //绑定滑动事件
 53         $list.on("scroll", function () {
 54             var height = this.clientHeight;
 55             var top = this.scrollTop;
 56             var totalHeight = this.scrollHeight;
 57             if (top + height - totalHeight == 0) {
 58                 more();
 59             }
 60         });
 61         //绑定搜索框事件enter事件
 62         $kw.on("keypress", function (e) {
 63             if (e.keyCode == 13) {
 64                 s();
 65             }
 66         });
 67         //绑定搜索按钮
 68         $(defaults.btnSelector).click(s);
 69     }
 70     //搜索
 71     function s() {
 72         //当前在加载中就返回
 73         if (flagloading != 0) {
 74             return;
 75         }
 76         flagloading = 1;
 77         //显示搜索动画
 78         layerIndex = layer.open({ type: 2 });
 79         keyword = $kw.val();
 80         $.ajax({
 81             url: defaults.url,
 82             data: defaults.getJson(true),
 83             type: "post",
 84             beforeSend: function () { },
 85             success: function (data) {
 86                 //搜索成功后移除所有列表项
 87                 $list.children(defaults.itemSelector).remove();
 88                 //如果返回的列表项不为空
 89                 if (data.trim()) {
 90                     $empty.remove();
 91                     //假设返回的为html,则可以直接插入到list
 92                     $list.append(data);
 93                     //将页数至为1
 94                     defaults.pageIndex = 1;
 95                 }
 96                 else {
 97                     //列表为空,将空列表效果添加到list
 98                     $empty.appendTo($list);
 99                     defaults.pageIndex = 0;
100                 }
101             },
102             error: function () { },//页数不变,列表数据不清空
103             complete: function () {
104                 //关闭搜索动画
105                 layer.close(layerIndex);
106                 //更改状态为非加载中
107                 flagloading = 0;
108             }
109         });
110     }
111 
112     function more() {
113         //获取当前页数
114         var _pageIndex = defaults.pageIndex;
115         if (flagloading == 1) {
116             return;
117         }
118         $.ajax({
119             url: defaults.url,
120             type: "post",
121             data: defaults.getJson(false),
122             beforeSend: function () {
123                 $empty.remove();
124                 //将加载效果添加到列表
125                 $loading.appendTo($list);
126                 flagloading = 1;
127             },
128             success: function (data) {
129                 //返回数据不为空
130                 if (data.trim()) {
131                     //假设返回的是html
132                     $list.append(data);
133                     //将当前页数+1
134                     defaults.pageIndex += 1;
135                 }
136                 //返回数据为空
137                 else {
138                     //当请页数为0
139                     if (defaults.pageIndex == 0) {
140                         //将空列表效果加入到list
141                         if ($list.children(".empty").length == 0) {
142                             $empty.appendTo($list);
143                         }
144                     }
145                 }
146             },
147             complete: function () {
148                 //移除加载效果
149                 $loading.remove();
150                 setTimeout(function () { flagloading = 0; }, 200);
151             }
152         });
153     }
154 }
View Code

  3、然后是示例

  本实现有两个视图,一个是主视图,list定义在其中。一个是局部视图,用于快速生成列表项的HTML。

 1 @using System.Collections.Generic
 2 @model List<string>
 3 @{
 4     Layout = null;
 5 }
 6 
 7 <!DOCTYPE html>
 8 
 9 <html>
10 <head>
11     <meta name="viewport" content="width=device-width" />
12     <title>SlidingLoading</title>
13     <link href="~/css/slidingloading.css?v=3" rel="stylesheet" />
14     <style>
15         .title{
16             text-align:center;
17             font-size:1.2rem;
18 
19         }
20         .searh-wrapper{
21             display:flex;   
22             justify-content:center;
23             padding:1rem;
24         }
25     </style>
26 </head>
27 <body>
28     <div class="title">
29         <label>轻量简易分页工具</label>
30     </div>
31     <div class="searh-wrapper">
32         <input type="search" name="kw" id="kw" /><button id="btn-search">搜索</button>
33     </div>
34     <div class="list">
35         @Html.Partial("SlidingLoading.partial", Model)
36     </div>
37     <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
38     <script src="https://cdn.bootcss.com/layer/3.1.0/mobile/layer.js"></script>
39     <script src="~/js/slidingloading.js"></script>
40     <script>
41         var pager = new SlidingLoading();
42         pager.init({
43             pageIndex: 1,//当前显示到第几页
44             listSelector: ".list",//列表id或class
45             itemSelector: ".item",//列表项的class
46             btnSelector: "#btn-search",//搜索按钮
47             kwSelector:"#kw",//搜索关键字输入框
48         });
49     </script>
50 </body>
51 </html>
View Code
1 @using System.Collections.Generic
2 @model List<string>
3 
4 @foreach (var item in Model)
5 {
6     <div class="item">
7         <label>@item</label>
8     </div>
9 }
View Code
 1 *{
 2     padding:0;
 3     margin:0;
 4     box-sizing:border-box;
 5 }
 6 html,body{
 7     width:100%;
 8     height:100%;
 9     font-size:14px;
10     background-color:whitesmoke;
11 }
12 body{
13     display:flex;   
14     flex-direction:column;
15     align-items:stretch;
16 }
17 /*列表的高度必须固定,且overflow-y必须为auto*/
18 .list{
19     overflow-x:hidden;
20     overflow-y:auto;
21     position:relative;/*很重要,配合item的absolute*/
22     padding-bottom:3rem;
23     flex:1;
24 }
25 /*item必须是list的直接子元素*/
26 .list>.item{
27     width:100%;
28     margin-top:1rem;
29     padding:2rem;
30     background-color:white;
31 }
32 /*加载效果,空列表效果*/
33 .list > .loading,
34 .list > .empty {
35     display:flex;
36     align-items:center;
37     justify-content:center;
38     /*绝对定位很重要*/
39     position: absolute;
40     left:0;
41     right:0;
42     height:3rem;
43     
44 }
45 .list>.loading{
46     /*使加载框显示再列表最下面*/
47    margin-bottom:0;
48 }
View Code

 

效果图

posted @ 2018-03-10 15:43  網韻  阅读(349)  评论(0编辑  收藏  举报