mui初级入门教程(二)— html5+ webview 底部栏用法详解

文章来源:小青年原创
发布时间:2016-05-19
关键词:mui,html5+,webview
转载需标注本文原始地址: http://zhaomenghuan.github.io/

写在前面

本系列文章我们将利用mui基于网易云音乐API实现一个音乐播放器APP,同时基于环形或者融云实现聊天功能。作为本系列文章的第一篇,本文会详细讲解html5+中管理应用窗口界面的Webview模块的用法,因为是初级教程篇不过多讲解原理部分,初级用户只需要知道基本用法就可以,并使用mui.js中的组件进行页面效果展示。

webview基本知识

Webview模块管理应用窗口界面,实现多窗口的逻辑控制管理操作。通过plus.webview可获取应用界面管理对象。

什么是窗口?什么是webview?

这里我们首先来举个例子,大家都用过浏览器,常用的浏览器可以打开多个网页。电脑屏幕就是一个窗口,不同的页面我们可以什么是不同的webview,我们可以通过控制webview的切换从而控制浏览不同的页面。

对于我们这里就是一个html页面就是一个窗口,一个html页面可以创建多个webview。这个webview是原生APP中浏览网页的组件,android和iOS都有,html5plus中的webview是对原生webview的封装,可以用js进行调用,所以它的运行环境是APP环境,普通浏览器不支持。

首先我们现在html5plus官网看一下webview API文档,这里我们重点看一下下面几个方法:

创建新的Webview窗口

WebviewObject plus.webview.create( url, id, styles, extras );

说明:

创建Webview窗口,用于加载新的HTML页面,可通过styles设置Webview窗口的样式,创建完成后需要调用show方法才能将Webview窗口显示出来。

显示Webview窗口

void plus.webview.show( id_wvobj, aniShow, duration, showedCB, extras );

说明:

显示已创建或隐藏的Webview窗口,需先获取窗口对象或窗口id,并可指定显示窗口的动画及动画持续时间。

隐藏Webview窗口

void plus.webview.hide( id_wvobj, aniHide, duration, extras );

说明:

根据指定的WebviewObject对象或id隐藏Webview窗口,使得窗口不可见。

获取当前窗口的WebviewObject对象

WebviewObject plus.webview.currentWebview();

说明:

获取当前页面所属的Webview窗口对象。

查找指定标识的WebviewObject窗口

WebviewObject plus.webview.getWebviewById( id );

说明:

在已创建的窗口列表中查找指定标识的Webview窗口并返回。 若没有查找到指定标识的窗口则返回null,若存在多个相同标识的Webview窗口,则返回第一个创建的Webview窗口。 如果要获取应用入口页面所属的Webview窗口,其标识为应用的%APPID%,可通过plus.runtime.appid获取。

创建并打开Webview窗口

WebviewObject plus.webview.open( url, id, styles, aniShow, duration, showedCB );

说明:

创建并显示Webview窗口,用于加载新的HTML页面,可通过styles设置Webview窗口的样式,创建完成后自动将Webview窗口显示出来。

以上来源于html5plus文档,只列举了部分最常用的方法,旨在为后文做铺垫,由于不是文档,所以也得也不清楚,如果想详细了解请看这里html5plus webview API。

mui双webview模式

首先我们要了解mui为了解决窗体切换白屏和区域滚动提出的双webview模式。

页面初始化

mui框架将很多功能配置都集中在mui.init方法中,要使用某项功能,只需要在mui.init方法中完成对应参数配置即可,目前支持在mui.init方法中配置的功能包括:创建子页面、关闭页面、手势事件配置、预加载、下拉刷新、上拉加载、设置系统状态栏背景颜色。mui需要在页面加载时初始化很多基础控件,如监听返回键,因此务必在每个页面中调用.

以下是可以配置的参数:

mui.init({
//子页面
subpages: [{
//...
}],
//预加载
preloadPages:[
//...
],
//下拉刷新、上拉加载
pullRefresh : {
//...
},
//手势配置
gestureConfig:{
//...
},
//侧滑关闭
swipeBack:true, //Boolean(默认false)启用右滑关闭功能

//监听Android手机的back、menu按键keyEventBind: {    backbutton: false,  //Boolean(默认truee)关闭back按键监听    menubutton: false   //Boolean(默认true)关闭menu按键监听},//处理窗口关闭前的业务beforeback: function() {    //... //窗口关闭前处理其他业务详情点击 ↑ "关闭页面"链接查看},//设置状态栏颜色statusBarBackground: '# 9defbcg', //设置状态栏颜色,仅iOS可用preloadLimit:5//预加载窗口数量限制(一旦超出,先进先出)默认不限制

})
在app开发中,若要使用HTML5+扩展api,必须等plusready事件发生后才能正常使用,mui将该事件封装成了mui.plusReady()方法,涉及到HTML5+的api,建议都写在mui.plusReady方法中。

如下为打印当前页面URL的示例:

mui.plusReady(function(){
console.log("当前页面URL:"+plus.webview.currentWebview().getURL());
});

创建子页面

在mobile app开发过程中,经常遇到卡头卡尾的页面,此时若使用局部滚动,在android手机上会出现滚动不流畅的问题; mui的解决思路是:将需要滚动的区域通过单独的webview实现,完全使用原生滚动。具体做法则是:将目标页面分解为主页面和内容页面,主页面显示卡头卡尾区域,比如顶部导航、底部选项卡等;内容页面显示具体需要滚动的内容,然后在主页面中调用mui.init方法初始化内容页面。

mui.init({
subpages:[{
url:your-subpage-url,//子页面HTML地址,支持本地地址和网络地址
id:your-subpage-id,//子页面标志
styles:{
top:subpage-top-position,//子页面顶部位置
bottom:subpage-bottom-position,//子页面底部位置
width:subpage-width,//子页面宽度,默认为100%
height:subpage-height,//子页面高度,默认为100%
......
},
extras:{}//额外扩展参数
}]
});

参数说明:

styles:表示窗口属性,参考5+规范中的WebviewStyle;特别注意,height和width两个属性,即使不设置,也默认按100%计算;因此若设置了top值为非"0px"的情况,建议同时设置bottom值,否则5+ runtime根据高度100%计算,可能会造成页面真实底部位置超出屏幕范围的情况;left、right同理。

示例:Hello mui的首页其实就是index.html加list.html合并而成的,如下:

超级产品经理
M-BOX

        标题                首页                消息                设置; // 初始化mui.init()写在这里
首页的静态布局我们写完了,我们接下来新建三个含mui的html文件:1. 选择工程名,邮件就可以看到【新建】,然后就是选择【目录】新建文件夹和【html文件】新建含mui的html文件。我们新建一个文件夹html,并且在html文件夹下新建,home.html,message.html,setting.html。1. 在三个页面body之间分别输入mbody,就可以开始分别写页面了,比如可以先在页面上写上文件名,我们先来完善首页的子页切换逻辑。### 动态页面切换#### 1.创建子页面,首个选项卡页面显示,其它均隐藏;主要方法就是用plus.webview.create和plus.webview.hide();//设置默认打开首页显示的子页序号;var Index=0;//把子页的路径写在数组里面var subpages = ['html/home.html','html/message.html','html/setting.html'];//所有的plus-*方法写在mui.plusReady中或者后面。mui.plusReady(function() {    //获取当前页面所属的Webview窗口对象    var self = plus.webview.currentWebview();    for (var i = 0; i 注:如果Index不是0,需要将nav下的a标签中的.mui-active属性写到对应的a标签下。执行完我们会发现home.html的内容显示出来了,但是底部切换还不能,因为这里我们还没有监听底部的点击事件。在进行下一步之前,我们可以先做一个小实验,将上面的代码中的top或者bottom改为0,我们会发现,底部栏或者底部栏会被覆盖,这是因为mui一个重要的**潜规则**,**父子结构的页面子页面会比父页面层级高**,说白了就是子页面可以盖住父页面。这会导致开发者常犯的一个错误:将弹出层或者弹出菜单写在父页面被子页面盖住的bug。这里的apend()方法在html5plus文档中没有提到,这里的这个方法是将webview对象填充到窗口的方法。#### 2.选项卡点击事件mui 内部封装了一些常用的方法,其中DOM选择器、事件绑定等事件管理。具体可以参考文档:选择器、事件管理。mui()mui使用css选择器获取HTML元素,返回mui对象数组。1. mui("p"):选取所有p元素1. mui("p.title"):选取所有包含.title类的元素若要将mui对象转化成dom对象,可使用如下方法(类似jquery对象转成dom对象):

//obj1是mui对象
var obj1 = mui("# title");
//obj2是dom对象
var obj2 = obj1[0];

.on( event , selector , handler )1. eventType: String1. 需监听的事件名称,例如:'tap'1. selectorType: String-选择器1. handlerType: Function( Event event )1. 事件触发时的回调函数,通过回调中的event参数可以获得事件详情除了可以使用addEventListener()方法监听某个特定元素上的事件外, 也可以使用.on()方法实现批量元素的事件绑定。这里我们将为底部导航按钮添加事件://选项卡点击事件mui('.mui-bar-tab').on('tap', 'a', function(e) {    alert(true);});当我们点击底部选项卡的时候会弹出true,这不够,我们要能够分辨当前对象具体是哪一个,有两种思路:1. 第一我们能够知道当前点击的a标签所在序号就好了,就是找到index,然后根据上面那个subpages数组,利用plus.webview.show(subpages[index])方法显示。1. 我们给当前点击的a标签添加一个可以识别的属性,然后根据那个属性获取当前a的特征,然后就可以显示点击的子页,隐藏当前子页。第一种方法需要遍历此案获取index,第二种方法添加一个href很容易拿到子页id,我们采用第二种方案。getAttribute()getAttribute() 方法返回指定属性名的属性值。提示:如果您希望以 Attr 对象返回属性,请使用 getAttributeNode。于是我们可以这样写://当前激活选项var activeTab = subpages[Index],title=document.querySelector(".mui-title");//选项卡点击事件mui('.mui-bar-tab').on('tap', 'a', function(e) {    //获取目标子页的id    var targetTab = this.getAttribute('href');    if (targetTab == activeTab) {        return;    }    //更换标题    title.innerHTML = this.querySelector('.mui-tab-label').innerHTML;    //显示目标选项卡    plus.webview.show(targetTab);    //隐藏当前选项卡    plus.webview.hide(activeTab);    //更改当前活跃的选项卡    activeTab = targetTab;});### 兼容浏览器的处理办法这是后面补充的内容,最开始写的时候没有这个内容,在这里加上吧。为啥要加这个内容呢,因为很多人思维还是比较局限,用mui依然还是用原来的方法,有很多人依然使用href,之所以这么用就是大家改不了习惯,这就是被很多人说的坑。。。但是真的是坑吗?与其说是坑,我觉得是大家思维上没有转变过来,不明白mui为啥要禁用href这种方式,也不明白自己该怎么做。下面贴出一个用iframe代替多子webview形式的tabbar在浏览器的兼容处理方法:

var createIframe = function (el, opt) {
var elContainer = document.querySelector(el);
var wrapper = document.querySelector(".mui-iframe-wrapper");
if(!wrapper){
// 创建wrapper 和 iframe
wrapper = document.createElement('div');
wrapper.className = 'mui-iframe-wrapper';
for(var i in opt.style){
wrapper.style[i] = opt.style[i];
}
var iframe = document.createElement('iframe');
iframe.src = opt.url;
iframe.id = opt.id || opt.url;
iframe.name = opt.id;
wrapper.appendChild(iframe);
elContainer.appendChild(wrapper);
}else{
var iframe = wrapper.querySelector('iframe');
iframe.src = opt.url;
iframe.id = opt.id || opt.url;
iframe.name = iframe.id;
}
}

调用也很简单:

//当前激活选项
var activeTab = subpages[Index],title=document.querySelector(".mui-title");
mui('.mui-bar-tab').on('tap', 'a', function(e) {
// 获取目标子页的id
var targetTab = this.getAttribute('href');
if (targetTab == activeTab) {
return;
}
// 更换标题
title.innerHTML = this.querySelector('.mui-tab-label').innerHTML;
// 子页内容切换
if(mui.os.plus){
// 显示目标webview
plus.webview.show(targetTab);
// 隐藏当前webview
plus.webview.hide(activeTab);
// 更改当前活跃的选项卡
activeTab = targetTab;
}else{
// 创建iframe代替子页面
createIframe('.mui-content',{
url: targetTab,
style: {
top: '45px',//设置距离顶部的距离
bottom: '50px'//设置距离底部的距离
}
});
}
})

这样你就可以一套代码实现在多平台的利用啦,是不是很棒。## 后记虽然最后实现的效果很简单,好像直接看demo就可以写出来,但是新手甚至写了一段时间的同学也不见得对webview掌握得很好,这篇文章花了很长的篇幅去讲解webview的用法,旨在为新手建立一种学习mui这边的思路,那就是先看html5plus里面的模块,然后看mui对应的文档,最后看hello mui的demo,把握这种学习路线个人觉得是一种最佳的方案。本文作为系列文章第一篇讲代码的,所以做了很多铺垫,所以有一定基础的同学可能会觉得写得并没有什么看点,后面的肯定会有所不一样的。下一篇讲解的是网络请求XMLHttpRequest模块,下一讲会结合mui.ajax和网易云音乐API一起讲解。文章原始地址是我博客地址:http://zhaomenghuan.github.io最近在开始写MUI小白文档,地址:https://zhaomenghuan.gitbooks.io/mui/content/MUI小白文档git仓库地址:https://git.gitbook.com/zhaomenghuan/mui.git写文章不容易,也许写这些代码就几分钟的事,写一篇大家好接受的文章或许需要几天的酝酿,然后加上几天的码字,累并快乐着。如果文章对您有帮助请我喝杯咖啡吧!#html5plus、webview、mui、dcloud#

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部