HBuilder webApp开发(二)表格上拉加载更多下拉刷新[2017.05.24更新]

开始

《Swift 集成Alamofire/Kingfisher/MJRefresh/MBProgressHUD的小项目》利用showAPI上的接口,做了一个上下拉的小Demo。之后就没有什么时间搞Swift了,这个月发表博客的数量也没有上个月多了。这个月使用HBuilder搞WebApp,不管App怎样,也总算是学了一些东西。昨天周日一天没有出门,就自己新建了一个小的WebApp的项目,昨天就把代码敲好了,昨天的第一篇《 HBuilder webApp开发开发(一)新建项目》,但是没时间写第二篇博客,今天下班后就接着写第二篇。
关于表格的上下拉,个人感觉没有什么好写的,贴贴代码,以后遇见类似的就这么套就是了。但是在实际使用中还是有些问题:1.真机调试时安卓机的流畅度就没有苹果机的好,2.不知道是否有cell的重用,上拉的时候就在那里一直的appendChild。

效果图

为什么MarkDown不能设置图片大小呢?
这里写图片描述

代码

请求和样式都在一个html文件里面:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8">
        <title></title>
        <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <meta name="apple-mobile-web-app-status-bar-style" content="black">
        <link rel="stylesheet" href="../css/mui.min.css">
        <link rel="stylesheet" href="../css/app.css" />
    </head>
    <style>
        .head-part {
            padding-top: 10px;
        }
        .head-part #auther {
            height: 30px;
            line-height: 30px;
            margin-left: 70px;
        }
        .head-part #currentDate {
            height: 30px;
            width: 300px;
            line-height: 30px;
            margin-left: 70px;
            font-size: 14px;
        }
        .head-part .about-type {
            float: right;
            margin-right: 10px;
            text-align: right;
            text-overflow:ellipsis;
            overflow:hidden;
            white-space:nowrap; 
            width: 100px;
            color: red;
        }
        #headImage {
            width: 60px;
            height: 60px;
            border-radius: 30px;
            display: block;
            position: absolute;
            float: left;
        }
        #titleConcent {
            height: 110px;
        }
        #mainImage {
            padding-right: 10px;
            width: 100px;
            height: 100px;
            float: right;
        }
        #titleConcent1 {
            margin-top: 10px;
            height: 100px;
            text-overflow:ellipsis;
            overflow:hidden;
            line-height: 25px;
        }
        .mui-scroll .mui-table-view {
            padding-left: 10px;
        }
        .tableView-cell {
            list-style-type: none;
            /*设置下边框样式*/
            border-bottom-style: solid;
            border-bottom-width: 1px;
            border-bottom-color: #D3D3D3;
        }
        .mui-content{
            padding-top: 44px;
        }
        .mui-table-view:before{
            0px;
        }
        .mui-table-view:after{
            0px;
        }
    </style> 
    <body style="background-color: #D3D3D3;">
        <header class="mui-bar mui-bar-nav black">
            <h1 class="mui-title">消息</h1> 
        </header>
        <div class="mui-content">
            <!--下拉刷新容器-->
            <div id="pullrefresh" class="mui-content mui-scroll-wrapper">
            <div class="mui-scroll">
                <!--数据列表-->
                <ul class="mui-table-view" style="background-color: white;">
                    <li class="tableView-cell">
                        <!--<div class="head-part">
                            <img src="../images/shuijiao.jpg"/ id="headImage">
                            <div class="about-auther">
                                <div id="auther">
                                    作者名字<span class="about-type">印象派印象</span>
                                </div> 
                                <div id="currentDate">
                                    2016-05-16 10:22:12
                                </div>
                            </div>
                        </div>  
                        <div id="titleConcent">
                            <img src="../images/yuantiao.jpg" id="mainImage"/>
                            <div id="titleConcent1">
                                今天是2016.05.16,其实我的内心是奔溃的啊,加班!
                                今天是2016.05.16,其实我的内心是奔溃的啊,加班!
                                今天是 
                            </div>
                        </div>-->
                    </li>
                </ul>
            </div>
        </div>
        </div>      
    </body>
    <script src="../js/mui.js" ></script>
    <script type="text/javascript" charset="utf-8">
    var pageIndex = 1;  // 页数
    var allPages = 1;   // 总页数
    /*showAPI配置参数*/
    var appid = "19297"
    var sign = "56743e56cce6482eb499e0abb79a0c78"
    var baseUrl = "https://route.showapi.com/582-2?"
    var table = document.body.querySelector('.mui-table-view');

    (function($) {
            //阻尼系数 感觉在上拉时比较明显
            var deceleration = mui.os.ios ? 0.003 : 0.0009;
            $('.mui-scroll-wrapper').scroll({
                bounce: false,
                indicators: true, //是否显示滚动条
                deceleration: deceleration
            });
        })(mui);

        mui.init({
            pullRefresh: {
                container: '#pullrefresh',
                down: {
                    callback: pulldownRefresh
                },
                up: {
                    contentrefresh: '正在加载...',
                    callback: pullupRefresh
                }
            }
        });
        /**
         * 下拉刷新具体业务实现
         */
        function pulldownRefresh() {
            pageIndex = 1;
            console.log('下拉刷新');
            //table.innerHTML = '';
            setTimeout(function() {
                getaData();
                mui('#pullrefresh').pullRefresh().endPulldownToRefresh();
                mui('#pullrefresh').pullRefresh().refresh(true);
            }, 1000);
        }
        /**
         * 上拉加载具体业务实现
         */
        function pullupRefresh() {
            pageIndex = ++pageIndex;
            console.log(pageIndex);
            console.log('上拉加载更多');
            setTimeout(function() {
                getaData()
            }, 1000);
        }
        if (mui.os.plus) {
            mui.plusReady(function() {
                setTimeout(function() {
                    mui('#pullrefresh').pullRefresh().pulldownLoading(); 
                }, 500);
            });
        } else {
            mui.ready(function() {
                mui('#pullrefresh').pullRefresh().pulldownLoading();
            });
        }
        // 获取数据
        function getaData() {
            var timestamp = getDataStr();
            mui.plusReady(function() {
                mui.ajax(baseUrl, {
                    data: {
                        key: '',
                        typeId: '',
                        showapi_appid: appid,
                        showapi_sign: sign,
                        showapi_timestamp: timestamp,
                        page:pageIndex
                    },
                    dataType: 'json',
                    type: 'post',  
                    timeout: 10000,
                    beforeSend: function(data) {
                        plus.nativeUI.showWaiting(); 
                    },
                    success: function(data) {
                        plus.nativeUI.closeWaiting();  
                        if (data.showapi_res_code == 0) {
                            console.log("成功");
                            var dice1 = data.showapi_res_body;
                            var dice2 = dice1.pagebean;
                            var result = '';
                            if (pageIndex == 1) { //下拉刷新需要先清空数据
                                table.innerHTML = '';// 在这里清空可以防止刷新时白屏
                            }
                            allPages = dice2.allPages;/*获取总的分页数*/
                            /*表格填充数据 mui.each是异步的*/
                            mui.each(dice2.contentlist, function(index, item) {
                                var li = document.createElement('li');
                                li.url = item.url; /*详情url*/
                                li.title = item.title; /*详情标题*/
                                li.className = 'tableView-cell'; 

                                li.innerHTML = '<div class="head-part">'
                                + '<img src="' + item.userLogo + '"/ id="headImage">'
                                + '<div class="about-auther">'
                                + '<div id="auther">'
                                + item.userName 
                                + '<span class="about-type">' + item.typeName + '</span></div><div id="currentDate">'
                                + item.date + '</div></div></div><div id="titleConcent">'
                                + '<img src=" '+ item.contentImg + '" id="mainImage"/><div id="titleConcent1">'
                                + item.title + '</div></div>';                  
                                table.appendChild(li, table.firstChild);
                            });
                            if(pageIndex < allPages){
                                mui('#pullrefresh').pullRefresh().endPullupToRefresh(false);    /*能上拉*/
                            }else{
                                mui('#pullrefresh').pullRefresh().endPullupToRefresh(true);/*不能上拉*/
                            }
                        }
                    },
                    error: function(xhr, type, errerThrown) {
                        mui.toast('网络异常,请稍候再试');
                        plus.nativeUI.closeWaiting();  
                        mui('#pullrefresh').pullRefresh().endPullupToRefresh(true);
                    }
                });
            });
        }   
        // 获取当前时间 yyyyMMddHHmmss
        function getDataStr(){
            var date = new Date();
            var year = date.getFullYear();
            var mouth = date.getMonth() + 1;
            var day = date.getDate();
            var hour = date.getHours();
            var minute = date.getMinutes();
            var second = date.getSeconds();
            if(mouth < 10){ /*月份小于10  就在前面加个0*/
                mouth = String(String(0) + String(mouth));
            }
            var currentDate = String(year) + String(mouth) + String(day) + String(hour) + String(minute) + String(second);
            return currentDate;
        }

        //链接批量处理 页面跳转  
        var aniShow = "pop-in";
        mui('.mui-content').on('tap', 'li', function() {  
            console.log("detail-url -- >> " + this.url);  
            console.log("detail-title -- >> " + this.title);
            mui.openWindow({
                url: 'detail.html',
                id: 'detail',
                show: {
                    duration: 200,
                },
                waiting: {
                    autoShow: true
                },
                extras: {
                    detailUrl: this.url,
                    detailTitle: this.title
                },
            });
        });         
    </script>
</html>

思路

代码里面有注释,大致思路:
1.做一个刷新的容器;
2.加上一个可以上下滑动的scroll;
3.创建table;
4.创建cell;
5.等把cell的样式做好了就就可以把cell的代码注释掉,然后在请求回来数据的时候再写一次,只是这次是使用的网络数据。

关于上下拉

关于上下拉,其实也就是一些固定的思路,之前在写原生的iOS表格上下拉的时候基本也是一些固定的思路和方法。上下拉的思路和方法,可以看看《HTML5 WebApp开发(一)新建项目》提到的模板项目的目录examples/pullrefresh_sub.html这个html文件,只是这里我们使用的网路数据。

注意点

1.在下拉刷新的时候我们需要先清空使用table.innerHTML = ”;清空一下表格。关于在什么时候调用清空的方法,在代码里面有说明;
2.分页的处理,分页的处理基本和原生iOS开发时一样,无非就是判断当前页码是否是最后一页,最后一页的时候就不可以上拉了;

提高点

页面数据需要做缓存,在没有网络的时候,如果没有缓存,那么这个页面就空白的,这样的用户体验并不好。关于加缓存的问题,等有时间继续写这个代码的时候在来加。

最后

代码下载地址:请点击我!

更新日志

  • 2016-05-24

关于缓存的问题,在《提升HTML5的性能体验系列之一 避免切页白屏》,HBuilder提供了一些优化的方法,这些方法和数据缓存有些关系,但是我有我自己的想法,实际操作也是可行的。
声明一个全局变量例如revData(revData也可以使用其他方法永久存储起来),用来接收从服务器获取的数据。在显示的时候,我们做一个判断,当revData数据不为空的时候,我们就从revData解析数据显示,revData为空的时候我们就显示当前从网络获取的数据,由于初始是revData是空的所以第一次显示的是网络获取的数据,之后显示的是上次从网络获取的数据revData。为什么之后使用revData做显示时,图片可以显示出来呢?这是HBuilder帮我们把图片做了缓存处理,就像SDWebImage,我们只需要知道图片的url就可以从缓存中取到图片数据。但是使用只使用revData来缓存数据是存在问题的。如果在下次进入页面的时候,数据更新了怎么办?这个时候我们可以在服务器返回的json数据里面增加一个字段了如:update。当update=1时,表示数据发生了变化,这个时候我们就使用这次从网络获取的数据显示,当update=0,时,我们就使用上一次从服务器获取的数据revData去显示。对于图片数据和返回的json数据流来说,返回的json数据的数据量是很小的。

function showUpdate(){
        if (update == 1) { /*服务器有更新数据或者第一次请求update=1*/
            // 显示网路数据
        } else{ /*服务器没有数据更新*/
            if (revData == null) { /*没有缓存*/
                // 显示网络数据
            } else{ /*有缓存*/
                //显示缓存数据
            }
        }
    }

但是这样就又存在一个问题,服务器怎么知道前端是第几次请求数据呢,或者说第一次请求时update是多少。由于没做过页面缓存相关的,所以不知道怎么解这个问题。是否可以在接口里面增加终端设备的硬件参数呢?感觉这种做法是可以的。
代码已经同步到了我的github了。

更新 2017.05.24

在上面的代码其实一直存在bug,记得去年在写的时候,就知道这个Bug,然后一直没有修改。今天还是觉得修改了,不能误人。
BUG: 在安卓机上面,下拉刷新时,上面下拉的Loading框在导航栏上面,苹果手机不存在这个问题。
解决方案:把这个页面拆分为父子页面。
这里写图片描述
代码部分直接更新到了我的github

猜你喜欢

转载自blog.csdn.net/zhuming3834/article/details/51485074