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         }

  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 = $("
", { class: "loading" }).html(""); 11 //空列表效果元素 12 var $empty = $("
", { class: "empty" }).html(""); 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 }

  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>SlidingLoadingtitle>
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>
1 @using System.Collections.Generic
2 @model List<string>
3 
4 @foreach (var item in Model)
5 {
6     <div class="item">
7         <label>@itemlabel>
8     div>
9 }
 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 }

效果图