首先我们需要去安装一个开发工具 HBuilder X
和 模拟器(也可以连接手机进行开发),这是 HBuilder X 的下载地址 http://www.dcloud.io;模拟器我用网易的 MuMu
,下载地址 http://mumu.163.com。
创建项目流程:选择 5+App
,添加已包含 mui
的项目模板
然后可以在页面添加各样的组件,例如添加一个侧滑菜单栏,再加一个图片轮播框和图文列表,因为数据都是动态的,所以我只保留了图片轮播、图文列表的框架存在,下面利用 ajax 请求进行数据获取。
数据源我使用的是 知乎日报API ,在这项目当中我用了3个链接,里面还有其它的 API 地址,如有需要的可供去选择。
<body>
<div class="mui-off-canvas-wrap mui-draggable">
<div class="mui-inner-wrap">
<aside class="mui-off-canvas-left" id="offCanvasSide">
<div class="mui-scroll-wrapper">
<div class="mui-scroll">
div>
div>
aside>
<header class="mui-bar mui-bar-nav">
<a class="mui-icon mui-action-menu mui-icon-bars mui-pull-left" href="#offCanvasSide">a>
<h1 class="mui-title">知乎日报h1>
header>
<div class="mui-content mui-scroll-wrapper" id="refreshContainer">
<div class="mui-scroll">
<div style="margin: 0.2rem;">div>
<div class="mui-slider">
<div class="mui-slider-group mui-slider-loop" id="aa">div>
div>
<div id="redian">今日热点div>
<div id="loop_centen">
div>
div>
div>
<div class="mui-off-canvas-backdrop">div>
div>
div>
body>
首先是页面加载后初始化下拉刷新和上拉加载,利用选择器来获取待刷新的容器位置。
注: 如果用 mui.init()
方法来进行初始化则有可能发生 事件无效 或者 容器无法滚动 情况,这个问题我掉坑了几天没解决的,后来自己来初始化 pullRefresh()
后问题就解决了,上拉加载与下拉刷新都是用一个 pullRefresh()
方法进行初始化。
<script src="js/mui.min.js"></script>
<script type="text/javascript" charset="utf-8">
mui("#refreshContainer").pullRefresh({
up: {
height: 30, //可选.默认50.触发上拉加载拖动距离
auto: false, //可选,默认false.自动上拉加载一次
contentrefresh: '正在加载...', //可选,正在加载状态时,上拉加载控件上显示的标题内容
contentnomore: '没有更多数据了', //可选,请求完毕若没有更多数据时显示的提醒内容
callback: jiazai //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据;
},
down: {
auto: true, // 可选,默认false.首次加载自动下拉刷新一次
contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容
contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容
contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容
callback: refresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据;
}
})
// 定义两个全局变量,一个用于计数(后面上拉加载会用到),一个存放日期
var nums = 0;
var riqi = '';
// 首页加载
function refresh() {
// 两个变量用于存放元素
let html = '';
let centen = '';
// 获取图片轮播框的位置
var lunbo = mui("#aa");
// 请求数据
mui.ajax('https://news-at.zhihu.com/api/4/news/latest', {
dataType: 'json', //服务器返回json格式数据
type: 'GET', //HTTP请求类型
headers: {
"Content-Type": "application/json"
}, // 设置访问表头,用于解决跨域问题
timeout: 10000, //超时时间设置为10秒;
success: function(data) {
// 设置轮播第一张图片
var firstImage = " ";
// 设置轮播最后一张图片
var lastImage = " ";
// 把第一张图片放到 html 中
html += firstImage;
// 循环轮播集合把数据取出来分别放到 html 中
mui.each(data.top_stories, function(index, object) {
html += " ";
});
// 最后一张图片放到 html 中
html += lastImage;
var loop = lunbo[0];
loop.innerHTML = html;
// 获得 slider 插件对象,用于设置轮播图框是否自动轮播,时间是多长
var gallery = mui('.mui-slider');
gallery.slider({
interval: 3000 // 自动轮播周期,若为 0 则不自动播放,默认为0
});
// 设置今日热点新闻
mui.each(data.stories, function(indexs, object) {
centen += '' ;
// 新闻详细信息,跳转页面同时把 新闻id 传过去
centen += '';
centen += '+ object.images + '">';
centen += object.title;
centen += '';
centen += '';
});
// 把今日新闻数据集插入到列表中
document.getElementById("loop_centen").innerHTML = centen;
// 给主容器内的 表签绑定单击事件,单击后跳转新闻详细页面
// 注:在 mui 中的 click 事件有时候会失效,改用 tap 事件,该事件与 click 一样
mui("#refreshContainer").on('tap', 'a', function() {
var id = this.getAttribute('href');
mui.openWindow({
// 新窗口的id
id: 'new_file',
// 新窗口的地址
url: 'new_file.html',
// 新闻 id 参数
extras: {
sid: id
}
})
});
// 定时器多少秒后执行下面方法
setTimeout(function() {
// endPulldownToRefresh() 方法是结束下拉刷新,括号内参数是 true|false,
// 如果参数为 false 则代表还有更多数据则继续,参数为 true 则显示没有新数据刷新;
mui("#refreshContainer").pullRefresh().endPulldownToRefresh();
}, 1000);
// 把计数重置(具体作用下面的上拉加载会讲解);
nums = 0;
}
});
}
nums
参数 的作用来了,主要用于 首次计数,因为知乎日报的过往信息是查询当天日期返回前一天的新闻,首次加载过往新闻 tapscroll()
方法是不进行传日期参数的,而是自己 获取当天时间然后进行拼接日期,当第二次加载过往新闻,则根据返回的 date 日期参数继续查询。
至于上面的刷新方法为什么要把 nums
计算参数重置,当我们有进行过上拉加载过往新闻后,此时 nums > 0
的,如果下拉刷新一次数据后,不把 nums
计算参数重置,再次上拉加载过往新闻时则会根据上次加载到哪一天的日期来显示出来,所以需要把 nums
计算参数重置为 0
,加载过往新闻时候才会从当天开始加载。
// 上拉加载过往新闻
function jiazai() {
// 定时器,作用与下拉刷新一样
setTimeout(function() {
if (nums == 0) {
// 首次加载过往新闻
// 调用上拉加载的方法
riqi = tapscroll();
// 加载一次后 计算参数 nums 自身 ++
nums++;
// endPullupToRefresh 用于是否接收上拉加载动作,参数为 true|false,
// 根据返回的 riqi 是否为空,空则代表没有过往新闻了,则上拉动作继续,否则显示没有更多数据了
mui("#refreshContainer").pullRefresh().endPullupToRefresh(riqi == null);
} else {
// 第二次加载过完新闻
riqi = tapscroll(riqi);
nums++;
mui("#refreshContainer").pullRefresh().endPullupToRefresh(riqi == null);
}
}, 1000);
}
tapscroll()
方法的 dates
参数是日期,根据参数判断 dates
是否为 null
或 underfined
,如果为空则获取当前的日期。
注: underfined
必须带上 引号 ,如果不带引号,则会报 underfined is not defined
错误,我个人理解的原因是, underfined
本身是可变的对象类型,字符串与它比较不了,需要把变为字符串类型后再进行比较。
// 上拉加载新闻
function tapscroll(dates) {
// 过往新闻 url
var url = 'https://news-at.zhihu.com/api/4/news/before/';
if (dates == null || dates == "underfined") {
// 获取当前日期
var now = new Date();
var year = now.getFullYear(); //年
var month = now.getMonth() + 1; //月
var day = now.getDate();
if (month < 10) month = "0" + month;
if (day < 10) day = "0" + day;
riqi = year + month + day;
url += riqi;
} else {
url += dates;
}
mui.ajax(url, {
dataType: 'json', //服务器返回json格式数据
type: 'get', //HTTP请求类型
async: false,
headers: {
'Content-Type': 'application/json'
},
timeout: 10000, //超时时间设置为10秒;
success: function(data) {
//alert(data.stories);
// 设置今日热点新闻
var centen = '';
centen = '' + data.date + '';
mui.each(data.stories, function(indexs, object) {
centen += '' ;
// 新闻详细信息,跳转页面同时把 新闻id 传过去
centen += '';
centen += '+ object.images + '">';
centen += object.title;
centen += '';
centen += '';
});
// 把过往新闻数据集插入容器中
document.getElementById("loop_centen").innerHTML += centen;
// 保存数据集的日期,用于继续查询再往后一天
riqi = data.date;
}
});
// 返回日期
return riqi;
}
注: 需把 ajax
请求设置为同步请求,如果是异步请求,则会导致 riqi
参数为空。
原因: 因为是异步请求,success
函数的执行步骤是不按照代码顺序来的,数据集还没有有返回回来,riqi
参数就已经 先返回 了,就算最后数据渲染出来了,但是 riqi
参数依然为空,所以需把 ajax
请求设置为 同步。
index 页面的代码就是这样,有些需要注意的点我也在代码中注释出来了,可以根据着进行理解。
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>title>
<link href="css/mui.min.css" rel="stylesheet" />
<script src="js/mui.min.js">script>
head>
<body>
<header class="mui-bar mui-bar-nav">
<a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left">a>
<h1 class="mui-title">详细新闻页面h1>
header>
<div id="content" class="mui-content mui-scroll-wrapper">
div>
body>
<script type="text/javascript">
mui.plusReady(function() {
// plus.webview.currentWebview 方法个人理解是:获取当前窗口对象
var self = plus.webview.currentWebview();
// 通过窗口对象获取从 index 页面传过来的新闻 id
var url = 'https://news-at.zhihu.com/api/4/news/' + self.sid;
// 渲染详细新闻
onloadXinWen(url);
})
function onloadXinWen(url) {
mui.ajax(url, {
dataType: 'json', //服务器返回json格式数据
type: 'get', //HTTP请求类型
timeout: 10000, //超时时间设置为10秒;
headers: {
'Content-Type': 'application/json'
},
success: function(data) {
document.getElementById('content').innerHTML = "";
}
});
}
script>
html>
一个简单的 Mui 项目就是完成了,如有学习到,麻烦各位大佬个赞,分析代码不容易;有什么建议或者意见可以提出来,我会进行修正。