HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

承接APP项目开发,有需要的朋友可以看下(信息长期有效)

5+App开发

承接 APP项目开发,请有需要的朋友可以提供下详细的需求文档,并且提供APP UI原型图(如果没有ui原型图的,可以我们根据提供文档需求,免费设计APP原型图,以便大家能了解整个开发

需求)

联系QQ 1795977154(加Q时请说明dcloud app),信息长期有效

交易:1、淘宝 2、对公转账(推荐),需要签订合同,个人开发者请选择淘宝

实力团队开发,众多成功案例(感谢dcloud提供这么好的一个平台)

想便宜的,找个人去开发吧(经常会:出差、家里有人生病住院、网络掉线、在外面办事、生病在打点滴、消失几天+、项目开发遥遥无期、投诉无门)

说明一点:app开发成本起步价为8万+,如果想几千或者5万以内能开发的,请绕过,我们大家都挺忙的!

说明一点:
1,没有详细需求文档的,请绕过,(如果你无法简洁的表达你的想法,那只说明你还不够了解它。 -- 阿尔伯特·爱因斯坦)

在强调2点:
1、没有后台的就需要开发后台,不要问我这个有什么用,我不会详细的去和你解释程序开发是如何实现的(只会简单说明,不理解的就对了,等你都理解了,你自己都可以开发了),因为这个不是在

一对一技术培训,我们是在为你开发程序,如何开发你可以百度去看网上的视频,他们比我们说的更详细一些。
2、有后台的,请提供api接口,没有api接口的,我们是收费开发的。

最后强调一点:
app开发成本是比较高的,不了解的就请认真考虑我们的报价和解决方案,不要动不动就乱说一通,还骂收费坑人,说难听一点的,就是你们自己公司或者个人平时都是这样坑人的,你自己才会觉得别

人都是在坑你,这个是素质问题,和开发无关,大家都挺忙的,没时间扯嘴皮子。一个报价和解决方案都是会有他自己的因素决定的,现在开发价格都比较透明,对比一下就知道了,为了生存,没有

哪个公司会报搞得离谱的价格,这样会流失客户,同样,也没有哪个公司会亏本赚吆喝,毕竟我们没有锤子的情怀。

我们不是最好的,但是我们一定是用心在和你沟通的,我们一定是用心在给你开发的,不虚报价格,中途不变相收费(不会低价引诱,中途增加额外费用,当然增加功能开发的除外)

提示:我们不接半路转手的单子,如果是半路转手或者需要修改的,请勿打扰,谁给你们做的,你们找他们去。

继续阅读 »

承接 APP项目开发,请有需要的朋友可以提供下详细的需求文档,并且提供APP UI原型图(如果没有ui原型图的,可以我们根据提供文档需求,免费设计APP原型图,以便大家能了解整个开发

需求)

联系QQ 1795977154(加Q时请说明dcloud app),信息长期有效

交易:1、淘宝 2、对公转账(推荐),需要签订合同,个人开发者请选择淘宝

实力团队开发,众多成功案例(感谢dcloud提供这么好的一个平台)

想便宜的,找个人去开发吧(经常会:出差、家里有人生病住院、网络掉线、在外面办事、生病在打点滴、消失几天+、项目开发遥遥无期、投诉无门)

说明一点:app开发成本起步价为8万+,如果想几千或者5万以内能开发的,请绕过,我们大家都挺忙的!

说明一点:
1,没有详细需求文档的,请绕过,(如果你无法简洁的表达你的想法,那只说明你还不够了解它。 -- 阿尔伯特·爱因斯坦)

在强调2点:
1、没有后台的就需要开发后台,不要问我这个有什么用,我不会详细的去和你解释程序开发是如何实现的(只会简单说明,不理解的就对了,等你都理解了,你自己都可以开发了),因为这个不是在

一对一技术培训,我们是在为你开发程序,如何开发你可以百度去看网上的视频,他们比我们说的更详细一些。
2、有后台的,请提供api接口,没有api接口的,我们是收费开发的。

最后强调一点:
app开发成本是比较高的,不了解的就请认真考虑我们的报价和解决方案,不要动不动就乱说一通,还骂收费坑人,说难听一点的,就是你们自己公司或者个人平时都是这样坑人的,你自己才会觉得别

人都是在坑你,这个是素质问题,和开发无关,大家都挺忙的,没时间扯嘴皮子。一个报价和解决方案都是会有他自己的因素决定的,现在开发价格都比较透明,对比一下就知道了,为了生存,没有

哪个公司会报搞得离谱的价格,这样会流失客户,同样,也没有哪个公司会亏本赚吆喝,毕竟我们没有锤子的情怀。

我们不是最好的,但是我们一定是用心在和你沟通的,我们一定是用心在给你开发的,不虚报价格,中途不变相收费(不会低价引诱,中途增加额外费用,当然增加功能开发的除外)

提示:我们不接半路转手的单子,如果是半路转手或者需要修改的,请勿打扰,谁给你们做的,你们找他们去。

收起阅读 »

30天开发一款你想要的APP!

mui HBuilder

东翌学院

在今年这个时间开始学习移动开发真是最好不过了,每个人应该都有一些移动应用的创意,而且你并不需要任何的原生应用编程经验,你只需要一些HTML的相关知识, 懂一些CSS和JavaScript就够了,跨平台移动APP开发是利用HTML5+CSS3+JS,快速开发出本地App,一次开发,多平台适配,效果与原生App相媲美。学习跨平台app开发就在这里>>>立即学习 咨询电话:010-57201298 QQ:410355878

  1. 选择开发技术和工具

开发跨平台移动App的最大挑战之一,就是每个移动平台就有个原生语言和软件开发包(SDK):Windows手机是C#和.Net,iOS平台使用Objective C和Cocoa,而Android则是Java和ADK。对此,我们可以找到代码分享的方法,而HTML5用C++编码,所以可以用于三个平台。

当然,使用每个平台的原生语言和软件开发包,可以最大发挥平台的完整功能性,开发简便也能保证高性能。还能迅速升级为操作系统和软件开发包的最新版本,充分运用新特性。为了获得最佳用户体验,原生平台的优势是非常明显的。

HTML5则能通过更新网络服务器来更新App的功能,这对某些App来说非常有用。C++语言也对一些常见的跨平台组件十分有用。

然而,在以上两种情况下要发挥平台功能、编辑用户界面,是有些困难的。开发者仍然需要将原生软件开发包与一些选项相结合,来使用平台的独特功能。

  1. 明确用户体验

在某些情况下,每个平台想要的App功能是一样的,但是用户希望App在不同平台上的设计风格能够统一,这也就是这个App的个性。用户可以以此来感受App设计的价值感。有种设计理念是“App个性+平台外观和体验”。

App的个性,是指每个App都使用手段来突出自己,比如相似的颜色主题、特性和用户行为流。即使用户换了平台,他仍然能立刻上手。

平台的外观和体验,是让App的用户交互(UI)与同一平台的其他App统一,让用户立即就会使用。比如,常用图标放在屏幕的哪个位置。

  1. 短时间开发和测试

在移动App领域,淘汰率和竞争率都很高,用户会频繁更新。而传统的产品开发过程需要长期规划、开发和测试,耗费数月甚至上年时间。

好的解决方案就是使用快速发布周期。每个发布周期应包括一套相同特性,这只需要几周就可以开发出来,完整功能只在需要时才发布。

在稳定代码的同时,团队成员可以开始规划下一个发布周期,因此,发布周期可以不断循环,而用户可以不断更新,获得想要的功能。

继续阅读 »

东翌学院

在今年这个时间开始学习移动开发真是最好不过了,每个人应该都有一些移动应用的创意,而且你并不需要任何的原生应用编程经验,你只需要一些HTML的相关知识, 懂一些CSS和JavaScript就够了,跨平台移动APP开发是利用HTML5+CSS3+JS,快速开发出本地App,一次开发,多平台适配,效果与原生App相媲美。学习跨平台app开发就在这里>>>立即学习 咨询电话:010-57201298 QQ:410355878

  1. 选择开发技术和工具

开发跨平台移动App的最大挑战之一,就是每个移动平台就有个原生语言和软件开发包(SDK):Windows手机是C#和.Net,iOS平台使用Objective C和Cocoa,而Android则是Java和ADK。对此,我们可以找到代码分享的方法,而HTML5用C++编码,所以可以用于三个平台。

当然,使用每个平台的原生语言和软件开发包,可以最大发挥平台的完整功能性,开发简便也能保证高性能。还能迅速升级为操作系统和软件开发包的最新版本,充分运用新特性。为了获得最佳用户体验,原生平台的优势是非常明显的。

HTML5则能通过更新网络服务器来更新App的功能,这对某些App来说非常有用。C++语言也对一些常见的跨平台组件十分有用。

然而,在以上两种情况下要发挥平台功能、编辑用户界面,是有些困难的。开发者仍然需要将原生软件开发包与一些选项相结合,来使用平台的独特功能。

  1. 明确用户体验

在某些情况下,每个平台想要的App功能是一样的,但是用户希望App在不同平台上的设计风格能够统一,这也就是这个App的个性。用户可以以此来感受App设计的价值感。有种设计理念是“App个性+平台外观和体验”。

App的个性,是指每个App都使用手段来突出自己,比如相似的颜色主题、特性和用户行为流。即使用户换了平台,他仍然能立刻上手。

平台的外观和体验,是让App的用户交互(UI)与同一平台的其他App统一,让用户立即就会使用。比如,常用图标放在屏幕的哪个位置。

  1. 短时间开发和测试

在移动App领域,淘汰率和竞争率都很高,用户会频繁更新。而传统的产品开发过程需要长期规划、开发和测试,耗费数月甚至上年时间。

好的解决方案就是使用快速发布周期。每个发布周期应包括一套相同特性,这只需要几周就可以开发出来,完整功能只在需要时才发布。

在稳定代码的同时,团队成员可以开始规划下一个发布周期,因此,发布周期可以不断循环,而用户可以不断更新,获得想要的功能。

收起阅读 »

开发环境集成第三方sdk的一些建议cia验证码

1,代替短信验证码 cia验证码 sdk的集成

不仅仅是一种手机号码验证方式
更是APP真实用户身份识别最佳方案
用于APP注册真机本机识别
用于APP推广真实效果监控
用于APP奖励推荐作弊筛查
用于替代短信验证码
http://www.ciaapp.cn/

2,关于app的加密
通过360的加固宝加密后,虽然通过文件夹的方式看不到app的程序
但直接解压sdk后,仍可以看到源码
希望能有解决方案集成到开发环境或者打包服务器。

继续阅读 »

1,代替短信验证码 cia验证码 sdk的集成

不仅仅是一种手机号码验证方式
更是APP真实用户身份识别最佳方案
用于APP注册真机本机识别
用于APP推广真实效果监控
用于APP奖励推荐作弊筛查
用于替代短信验证码
http://www.ciaapp.cn/

2,关于app的加密
通过360的加固宝加密后,虽然通过文件夹的方式看不到app的程序
但直接解压sdk后,仍可以看到源码
希望能有解决方案集成到开发环境或者打包服务器。

收起阅读 »

MUI各种手势事件:滑动、拖动、点击等

MUI集成了很多手势事件,单击、长按、滑动等等。

点击事件:

  1. tap 单击屏幕
  2. doubletap 双击屏幕
    长按事件:
  3. longtap 长按屏幕
  4. hold 按住屏幕(为什么我想起了顶住屏幕)。。。
    3.release 离开屏幕
    滑动事件:
  5. swipeleft 向左滑动
  6. swiperight 向右滑动
  7. swipeup 向上滑动
  8. swipedown 向下滑动
    拖动事件:
  9. drastart 开始拖动
    2.drag 拖动中
  10. dragend 拖动结束

根据使用频率,mui默认会监听部分手势事件,如点击、滑动事件;为了开发出更高性能的moble App,mui支持用户根据实际业务需求,通过mui.init方法中的gestureConfig参数,配置具体需要监听的手势事件

注意:dragstart、drag、dragend 共用drag开关、swipeleft 、swiperight 、swipeup 、swipedown 共用swipe开关

事件监听:同标准的click事件冒泡一样,上面的事件支持任意添加到DOM对象上
例如 :Object.addEventListener("swipedown ",function(){

console.log("你向下滑动了");
})

网上搬运过来的,丰富社区的API文档-----紫苏

继续阅读 »

MUI集成了很多手势事件,单击、长按、滑动等等。

点击事件:

  1. tap 单击屏幕
  2. doubletap 双击屏幕
    长按事件:
  3. longtap 长按屏幕
  4. hold 按住屏幕(为什么我想起了顶住屏幕)。。。
    3.release 离开屏幕
    滑动事件:
  5. swipeleft 向左滑动
  6. swiperight 向右滑动
  7. swipeup 向上滑动
  8. swipedown 向下滑动
    拖动事件:
  9. drastart 开始拖动
    2.drag 拖动中
  10. dragend 拖动结束

根据使用频率,mui默认会监听部分手势事件,如点击、滑动事件;为了开发出更高性能的moble App,mui支持用户根据实际业务需求,通过mui.init方法中的gestureConfig参数,配置具体需要监听的手势事件

注意:dragstart、drag、dragend 共用drag开关、swipeleft 、swiperight 、swipeup 、swipedown 共用swipe开关

事件监听:同标准的click事件冒泡一样,上面的事件支持任意添加到DOM对象上
例如 :Object.addEventListener("swipedown ",function(){

console.log("你向下滑动了");
})

网上搬运过来的,丰富社区的API文档-----紫苏

收起阅读 »

修改官方demo选项卡+下拉刷新material风格为默认风格

下拉刷新 选项卡

官方demo的选项卡+下拉刷新采用mui.pullToRefresh.js+mui.pullToRefresh.material.js两个js插件来制作,这两个插件感觉像是官方写的,但是为啥接口参数非常相似但又不同,非常坑
下面是改写部分(两个demo的DOM结构一致)
使用插件的下拉刷新初始化写法(来自官方demo)


默认风格不使用插件的下拉刷新初始化写法(改写的demo,用了vue)

对比红框处的部分,太相似了很容易着道啊,不知道怎么想的。
选项卡下修改成默认风格的下拉刷新要重置下样式

原demo中初始化区域滚动也不要了,默认的下拉刷新会自己初始化,所以下图中的代码就不要了,不然会有两个滚动条

改后的效果图

继续阅读 »

官方demo的选项卡+下拉刷新采用mui.pullToRefresh.js+mui.pullToRefresh.material.js两个js插件来制作,这两个插件感觉像是官方写的,但是为啥接口参数非常相似但又不同,非常坑
下面是改写部分(两个demo的DOM结构一致)
使用插件的下拉刷新初始化写法(来自官方demo)


默认风格不使用插件的下拉刷新初始化写法(改写的demo,用了vue)

对比红框处的部分,太相似了很容易着道啊,不知道怎么想的。
选项卡下修改成默认风格的下拉刷新要重置下样式

原demo中初始化区域滚动也不要了,默认的下拉刷新会自己初始化,所以下图中的代码就不要了,不然会有两个滚动条

改后的效果图

收起阅读 »

MUI从入门到精通系列汇总

技术分享

mui初级入门系列教程

mui初级入门教程(一)— 小白入手mui的学习路线
mui初级入门教程(二)— html5+ webview 底部栏用法详解
mui初级入门教程(三)— html5+ XMLHttpRequest 与mui ajax用法详解
mui初级入门教程(四)— 再谈webview,从小白变“大神”!
mui初级入门教程(五)— 聊聊即时通讯(IM),基于环信 web im SDK
mui初级入门教程(六)— 模板页面实现原理及多端适配指南
mui初级入门教程(七)— 基于native.js的文件系统管理功能实现

mui-demo 仓库

easemobIM: 环信webim的demo
tabbar-div-animation: div模式带动画切换的选项卡
tabbar-with-popover:解决弹出层被遮挡的问题
timeline:时间轴效果
numberbox:倍率为2的范围可控的数字增减器
popover-control-byjs:js控制的popover
slider:加载网络图片的图片轮播
share: 使用图片打开分享(TODO)
piker: 选择器
preload:预加载注意事项
tabbar-webview-withleftmenu: 带侧滑的webview模式的tabbar
vue-mui: 基于Vue.js的mui tabbar演示例子
Statusbar:沉浸式状态栏
tab-with-segmented-control-vertical-uprefresh:左侧选项卡-div模式增加上拉加载功能
contenteditable:div contenteditable可编辑模式下【获得输入框键盘焦点】和【光标移动到最后】
pullrefresh-dtpiker:下拉刷新与时间选择器冲突的解决方案
calendar:日历组件
template:模板页面实现原理
tabbar-with-iframe iframe兼容处理tababr的方法
njs-io:基于native.js的文件系统管理功能实现
oauth:判断本地是否安装客户端,进行第三方登录
Audio: 录音转dataURI,dataURI转语音文件播放

mui文档番外版

mui组件通用CSS类
mui组件自定义样式
grid(栅格系统)
页面传参
template(模板页面)
input(输入表单)
文件IO

开发常见问题

1.如何获取文件的数据
2.打开系统wifi设置页面
3.沉浸式状态栏设置方法
4.上拉刷新下拉加载的启用禁止方法
5.如何设置相片分辨率
6.如何获取手机应用列表
7.可折叠列表的两个问题
8.5+webview与android原生Activity
9.获取APP系统权限和打开权限设置
10.录音文件与Base64编码相互转换的方法

DOM操作简化版

https://github.com/zhaomenghuan/mjs

继续阅读 »

mui初级入门系列教程

mui初级入门教程(一)— 小白入手mui的学习路线
mui初级入门教程(二)— html5+ webview 底部栏用法详解
mui初级入门教程(三)— html5+ XMLHttpRequest 与mui ajax用法详解
mui初级入门教程(四)— 再谈webview,从小白变“大神”!
mui初级入门教程(五)— 聊聊即时通讯(IM),基于环信 web im SDK
mui初级入门教程(六)— 模板页面实现原理及多端适配指南
mui初级入门教程(七)— 基于native.js的文件系统管理功能实现

mui-demo 仓库

easemobIM: 环信webim的demo
tabbar-div-animation: div模式带动画切换的选项卡
tabbar-with-popover:解决弹出层被遮挡的问题
timeline:时间轴效果
numberbox:倍率为2的范围可控的数字增减器
popover-control-byjs:js控制的popover
slider:加载网络图片的图片轮播
share: 使用图片打开分享(TODO)
piker: 选择器
preload:预加载注意事项
tabbar-webview-withleftmenu: 带侧滑的webview模式的tabbar
vue-mui: 基于Vue.js的mui tabbar演示例子
Statusbar:沉浸式状态栏
tab-with-segmented-control-vertical-uprefresh:左侧选项卡-div模式增加上拉加载功能
contenteditable:div contenteditable可编辑模式下【获得输入框键盘焦点】和【光标移动到最后】
pullrefresh-dtpiker:下拉刷新与时间选择器冲突的解决方案
calendar:日历组件
template:模板页面实现原理
tabbar-with-iframe iframe兼容处理tababr的方法
njs-io:基于native.js的文件系统管理功能实现
oauth:判断本地是否安装客户端,进行第三方登录
Audio: 录音转dataURI,dataURI转语音文件播放

mui文档番外版

mui组件通用CSS类
mui组件自定义样式
grid(栅格系统)
页面传参
template(模板页面)
input(输入表单)
文件IO

开发常见问题

1.如何获取文件的数据
2.打开系统wifi设置页面
3.沉浸式状态栏设置方法
4.上拉刷新下拉加载的启用禁止方法
5.如何设置相片分辨率
6.如何获取手机应用列表
7.可折叠列表的两个问题
8.5+webview与android原生Activity
9.获取APP系统权限和打开权限设置
10.录音文件与Base64编码相互转换的方法

DOM操作简化版

https://github.com/zhaomenghuan/mjs

收起阅读 »

给的例子也不调试完整,还要这样坑下初学者呀

你们的例子:
mui.ajax('http://server-name/login.php',{
data:{
username:'username',
password:'password'
},
dataType:'json',//服务器返回json格式数据
type:'post',//HTTP请求类型
timeout:10000,//超时时间设置为10秒;
headers:{'Content-Type':'application/json'}
success:function(data){
//服务器返回响应,根据响应结果,分析是否登录成功;
...
},
error:function(xhr,type,errorThrown){
//异常处理;
console.log(type);
}
});

继续阅读 »

你们的例子:
mui.ajax('http://server-name/login.php',{
data:{
username:'username',
password:'password'
},
dataType:'json',//服务器返回json格式数据
type:'post',//HTTP请求类型
timeout:10000,//超时时间设置为10秒;
headers:{'Content-Type':'application/json'}
success:function(data){
//服务器返回响应,根据响应结果,分析是否登录成功;
...
},
error:function(xhr,type,errorThrown){
//异常处理;
console.log(type);
}
});

收起阅读 »

怎么从零基础开始学习hbuilder+mui+h5+跨平台app开发?

HBuilder mui HelloH5 视频教程

推荐国内首推的跨平台移动APP开发专业培训机构-东翌学院是Dcloud的合作培训机构,跨平台APP开发整体课程在线直播+课程源码+全套视频,最新最全的APP开发,HB和MUI的全套视频,零基础都可以学习,更有高级进修课程,30天最快速的开发跨平台APP!
咨询报名QQ:2971611409 Tel:17090057793
欢迎有意向学习的朋友加好友咨询!谢谢Dcloud提供这么好的平台!

继续阅读 »

推荐国内首推的跨平台移动APP开发专业培训机构-东翌学院是Dcloud的合作培训机构,跨平台APP开发整体课程在线直播+课程源码+全套视频,最新最全的APP开发,HB和MUI的全套视频,零基础都可以学习,更有高级进修课程,30天最快速的开发跨平台APP!
咨询报名QQ:2971611409 Tel:17090057793
欢迎有意向学习的朋友加好友咨询!谢谢Dcloud提供这么好的平台!

收起阅读 »

【示例】App引导页的制作

示例 技术分享 Storage 引导页 mui

注意:本文为5+App的引导页制作方法,uni-app另行制作,推荐使用nvue制作,也可以参考插件市场已经封装的插件https://ext.dcloud.net.cn/plugin?id=192

启动页和引导页

首先澄清一下“启动界面”(splash)和“引导页”(guide)的概念,因为许多刚接触App开发的朋友会搞不清楚这两者分别是什么。
以Hello mui为例,第一次打开的时候是这样的:


首屏中MUI字样的图片就是splash,后面几个切换动画的界面则是guide。从第二次开始,再打开就直接进入App主界面了。
splash是每次启动都会看到的(每次打开QQ都会看到一只企鹅),但是guide是否展示是可控的(微博启动后经常会有广告页)。
ps:目前还不支持移除或动态设置splash。

示例实现

切回正题,一起来看一下类Hello mui这种引导页如何利用MUI&HTML5+进行制作。

App入口页

按照Hello mui这种启动页的逻辑:首次启动展示引导页,之后启动不再展示。那么就意味着,我们需要一个标识来确定,App是否已经启动过。
通过5+的storage模块的方法,我们可以在本地存储一个key来做为已经启动过App的标识。那么,我们在入口这里,就可以读取这个key,来决定是否展示引导页。

var launchFlag = plus.storage.getItem("launchFlag");  
if(launchFlag) {  
    mui.openWindow({  
        url: "main.html",  
        id: "main",  
        extras: {  
            mark: "index" //额外的参数,仅仅是个标识,实际开发中不用;  
        }  
    });  
} else {  
    mui.openWindow({  
        url: "guide.html",  
        id: "guide"  
    });  
}  

手动关闭splash

实际开发中,通常需要设置手动关闭splash(HBuilder7.1版本后启动界面不调用此方法超过6秒后会自动关闭),来控制App内容展示的时机。防止入口判定逻辑未结束就进行展示,造成白屏。

引导页

利用mui的slider组件,来制作一套引导信息。
如果使用图片的话,建议大家按照iPhone6 Plus的尺寸制作(其实就是往大了做),然后利用5+提供的方法计算屏幕正确的宽高,设置图片的宽高来撑满屏幕。相关文档及示例:
Screen模块管理设备屏幕信息
获取系统状态栏高度
深入理解高度。获取屏幕、webview、软键盘高度

var sh = plus.navigator.getStatusbarHeight();  
var h = plus.screen.resolutionHeight;  
var w = plus.screen.resolutionWidth;  
var imgs = document.querySelectorAll(".guide-img");  
for(var i = 0, len = imgs.length; i < len; i++) {  
    imgs[i].style.height = (h - sh) + "px";  
    imgs[i].style.width = w + "px";  
}  

在最后一个引导界面提供一个App主界面入口,也就是“开始体验”这种按钮。点击“开始体验”的同时,设置表示App已经启动过的标识。

plus.storage.setItem("launchFlag", "true");  

主界面

从第二次开始,启动应用直接进入主界面。

在主界面,额外提供了一个清除已经启动信息重启应用的功能,方便大家进行测试。

广告页

广告页其实也可以算是guide,只不过它引导的是广告信息。广告页只会在适当的时机出现,这个时机是由后端来决定的(通常情况下)。
广告页制作的逻辑:
1、入口处向后端发起请求,来得知是否存在广告;
2、若存在,则同时获取广告内容等信息;
3、广告内容按照固定的模板进行渲染,完成后关闭splash;
4、广告页持续特定的时间(通常就3-5秒)或提供按钮关闭,进入App主界面。

源码

附上源码,真机运行即可。

继续阅读 »

注意:本文为5+App的引导页制作方法,uni-app另行制作,推荐使用nvue制作,也可以参考插件市场已经封装的插件https://ext.dcloud.net.cn/plugin?id=192

启动页和引导页

首先澄清一下“启动界面”(splash)和“引导页”(guide)的概念,因为许多刚接触App开发的朋友会搞不清楚这两者分别是什么。
以Hello mui为例,第一次打开的时候是这样的:


首屏中MUI字样的图片就是splash,后面几个切换动画的界面则是guide。从第二次开始,再打开就直接进入App主界面了。
splash是每次启动都会看到的(每次打开QQ都会看到一只企鹅),但是guide是否展示是可控的(微博启动后经常会有广告页)。
ps:目前还不支持移除或动态设置splash。

示例实现

切回正题,一起来看一下类Hello mui这种引导页如何利用MUI&HTML5+进行制作。

App入口页

按照Hello mui这种启动页的逻辑:首次启动展示引导页,之后启动不再展示。那么就意味着,我们需要一个标识来确定,App是否已经启动过。
通过5+的storage模块的方法,我们可以在本地存储一个key来做为已经启动过App的标识。那么,我们在入口这里,就可以读取这个key,来决定是否展示引导页。

var launchFlag = plus.storage.getItem("launchFlag");  
if(launchFlag) {  
    mui.openWindow({  
        url: "main.html",  
        id: "main",  
        extras: {  
            mark: "index" //额外的参数,仅仅是个标识,实际开发中不用;  
        }  
    });  
} else {  
    mui.openWindow({  
        url: "guide.html",  
        id: "guide"  
    });  
}  

手动关闭splash

实际开发中,通常需要设置手动关闭splash(HBuilder7.1版本后启动界面不调用此方法超过6秒后会自动关闭),来控制App内容展示的时机。防止入口判定逻辑未结束就进行展示,造成白屏。

引导页

利用mui的slider组件,来制作一套引导信息。
如果使用图片的话,建议大家按照iPhone6 Plus的尺寸制作(其实就是往大了做),然后利用5+提供的方法计算屏幕正确的宽高,设置图片的宽高来撑满屏幕。相关文档及示例:
Screen模块管理设备屏幕信息
获取系统状态栏高度
深入理解高度。获取屏幕、webview、软键盘高度

var sh = plus.navigator.getStatusbarHeight();  
var h = plus.screen.resolutionHeight;  
var w = plus.screen.resolutionWidth;  
var imgs = document.querySelectorAll(".guide-img");  
for(var i = 0, len = imgs.length; i < len; i++) {  
    imgs[i].style.height = (h - sh) + "px";  
    imgs[i].style.width = w + "px";  
}  

在最后一个引导界面提供一个App主界面入口,也就是“开始体验”这种按钮。点击“开始体验”的同时,设置表示App已经启动过的标识。

plus.storage.setItem("launchFlag", "true");  

主界面

从第二次开始,启动应用直接进入主界面。

在主界面,额外提供了一个清除已经启动信息重启应用的功能,方便大家进行测试。

广告页

广告页其实也可以算是guide,只不过它引导的是广告信息。广告页只会在适当的时机出现,这个时机是由后端来决定的(通常情况下)。
广告页制作的逻辑:
1、入口处向后端发起请求,来得知是否存在广告;
2、若存在,则同时获取广告内容等信息;
3、广告内容按照固定的模板进行渲染,完成后关闭splash;
4、广告页持续特定的时间(通常就3-5秒)或提供按钮关闭,进入App主界面。

源码

附上源码,真机运行即可。

收起阅读 »

上传图片需要base64编码,Android和IOS完全兼容,也是弄了好久。

bitmap base64
 之前用H5的canvas来获取,但是只有Android可用,IOS不行,后来说用文件读取的形式,发现很慢,也麻烦,最后用bitmap,封装好的,直接用,两个平台都兼容。  

----分享一下^:^

function GetBase64Code(path) //path绝对路径  
{  
        var bitmap = new plus.nativeObj.Bitmap("test"); //test标识谁便取  
        // 从本地加载Bitmap图片  
        bitmap.load(path,function(){  
            var base4=bitmap.toBase64Data();  
            var datastr=base4.split(',',3)  
            if(datastr.length>1)  
            {  
               pics.push(datastr[1]);  
            }else  
            {  
               pics.push(datastr[0]);  
            }  
            console.log('加载图片:'+base4);  
        },function(e){  
            console.log('加载图片失败:'+JSON.stringify(e));  
        });  
}
继续阅读 »
 之前用H5的canvas来获取,但是只有Android可用,IOS不行,后来说用文件读取的形式,发现很慢,也麻烦,最后用bitmap,封装好的,直接用,两个平台都兼容。  

----分享一下^:^

function GetBase64Code(path) //path绝对路径  
{  
        var bitmap = new plus.nativeObj.Bitmap("test"); //test标识谁便取  
        // 从本地加载Bitmap图片  
        bitmap.load(path,function(){  
            var base4=bitmap.toBase64Data();  
            var datastr=base4.split(',',3)  
            if(datastr.length>1)  
            {  
               pics.push(datastr[1]);  
            }else  
            {  
               pics.push(datastr[0]);  
            }  
            console.log('加载图片:'+base4);  
        },function(e){  
            console.log('加载图片失败:'+JSON.stringify(e));  
        });  
}
收起阅读 »

个人全职承接 APP,thinkphp 接口+后台,完整项目 !保证质量 !

全职承接 APP,thinkphp 接口+后台,完整项目 !保证质量 !

QQ:2714055313,439396545!

两个QQ都可以联系!

全职承接 APP,thinkphp 接口+后台,完整项目 !保证质量 !

QQ:2714055313,439396545!

两个QQ都可以联系!

【示例】webview模式选项卡实现滑动切换

示例 选项卡 技术分享 Webview

关于选项卡切换,相信大家都不陌生。hello mui中提供了多种选项卡切换的实现方式,不过大体分为div模式(单页)以及webviedw模式(多个页面)。div模式中又提供了可左右拖动实现切换的模式,如图:

在实际开发中,数据量只会多不会少,因此我们通常都会采用webview模式选项卡。与此同时,许多同学依旧希望能够实现滑动来实现选项卡的切换。就像这样:

可能大家会说,这个滑动并不是那么灵敏。那是因为我控制的角度范围较小(更加精确方便的范围还在进一步测试),实际开发中大家可以根据自己的需求来修改这个范围。
一、main.html
在主页面,我们需要做许多事情,创建自窗口对象(不然切什么换),底部选项点击切换(这是基本的切换),自定义事件切换(子窗口滑动事件来触发)。
其中关键的地方,在于切换。切换,我们要切什么,换什么这才是选项卡切换的核心。
切,有两种切法,点击和滑动。
换,换子窗口,换标题,换底部高亮文字。

<!doctype html>  
<html>  

    <head>  
        <meta charset="UTF-8">  
        <title></title>  
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />  
        <link href="http://ask.dcloud.net.cn/css/mui.min.css" rel="stylesheet" />  
    </head>  

    <body>  
        <header class="mui-bar mui-bar-nav">  
            <h1 class="mui-title">首页</h1>  
        </header>  
        <nav class="mui-bar mui-bar-tab">  
            <a class="mui-tab-item mui-active" data-index="0">  
                <span class="mui-icon mui-icon-home"></span>  
                <span class="mui-tab-label">首页</span>  
            </a>  
            <a class="mui-tab-item" data-index="1">  
                <span class="mui-icon mui-icon-phone"></span>  
                <span class="mui-tab-label">电话</span>  
            </a>  
            <a class="mui-tab-item" data-index="2">  
                <span class="mui-icon mui-icon-email"></span>  
                <span class="mui-tab-label">邮件</span>  
            </a>  
            <a class="mui-tab-item" data-index="3">  
                <span class="mui-icon mui-icon-gear"></span>  
                <span class="mui-tab-label">设置</span>  
            </a>  
        </nav>  
        <script src="js/mui.min.js"></script>  
        <script type="text/javascript">  
            mui.init();  
            mui.plusReady(function() {  
                /**  
                 * 当前窗口对象,即父窗口;  
                 * http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.currentWebview  
                 */  
                var self = plus.webview.currentWebview();  
                // 子窗口地址数组  
                var subpages = ["home.html", "phone.html", "email.html", "gear.html"];  
                // 子窗口样式  
                var subStyles = {  
                    top: "45px",  
                    bottom: "50px"  
                };  
                // 子窗口数量  
                var subLen = subpages.length;  
                // 子窗口对象数组  
                var subWvs = [];  
                // 标题栏  
                var title = document.querySelector(".mui-title");  
                // 底部选项  
                var tabs = document.querySelectorAll(".mui-tab-item");  
                // 底部文字  
                var labels = document.querySelectorAll(".mui-tab-label");  
                // 当前页面索引,初始化为0;  
                var activeIndex = 0;  
                // 目标页面索引,初始化为当前页面索引;  
                var targetIndex = activeIndex;  
                // 创建子页面  
                for(var i = 0; i < subLen; i  ) {  
                    /**  
                     * 创建窗口对象,并将索引做为额外的参数传递;  
                     * http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.create  
                     */  
                    var subWv = plus.webview.create(subpages[i], cutWebviewId(subpages[i]), subStyles, {  
                        index: i  
                    });  
                    // 窗口对象添加至数组  
                    subWvs.push(subWv);  
                    if(i > 0) {  
                        /**  
                         * 隐藏非第一页的窗口对象  
                         * http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewObject.hide  
                         */  
                        subWv.hide("none");  
                    }  
                    /**  
                     * 向父窗口添加子窗口  
                     * http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewObject.append  
                     */  
                    self.append(subWv);  
                }  
                // 底部选项卡点击切换事件  
                for(var j = 0, jlen = tabs.length; j < jlen; j  ) {  
                    tabs[j].addEventListener("tap", function() {  
                        // 获取当前结点的索引  
                        targetIndex = this.getAttribute("data-index");  
                        // 转换为number类型  
                        targetIndex = parseInt(targetIndex, 10);  
                        if(targetIndex == activeIndex) {  
                            return;  
                        }  
                        // 切换页面  
                        switchPage("tap", activeIndex, targetIndex);  
                    });  
                }  
                // 子页面滑动切换事件  
                window.addEventListener("swipe_event", function(event) {  
                    // 获取方向以及索引  
                    var direction = event.detail.direction;  
                    activeIndex = event.detail.index;  
                    if(direction == "left") {  
                        // 如果是最后一个页面,则不做左滑切换;  
                        if(activeIndex == subLen - 1) {  
                            console.log("最右边一页了");  
                            return;  
                        }  
                        // 目标页面的索引为后面一位  
                        targetIndex = activeIndex   1;  
                    } else {  
                        // 如果是第一个页面,则不做右滑切换;  
                        if(activeIndex == 0) {  
                            console.log("最左边一页了");  
                            return;  
                        }  
                        // 目标页面的索引为前面一位  
                        targetIndex = activeIndex - 1;  
                    }  
                    // 切换页面  
                    switchPage("switch", activeIndex, targetIndex);  
                });  

                /**  
                 * 切换页面  
                 * @param {String} _event 事件类型  
                 * @param {Number} _active 当前页面索引  
                 * @param {Number} _target 目标页面索引  
                 */  
                function switchPage(_event, _active, _target) {  
                    /**  
                     * 目标页面展示  
                     * http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewObject.show  
                     */  
                    subWvs[_target].show("fade-in");  
                    // 顶部文字替换  
                    title.innerText = labels[_target].innerText;  
                    // 如果是滑动事件,则手动切换高亮选项;  
                    if(_event == "switch") {  
                        tabs[_active].classList.remove("mui-active");  
                        tabs[_target].classList.add("mui-active");  
                    }  
                    // 之前展示的页面隐藏  
                    subWvs[_active].hide("none");  
                    // 更新当前页索引  
                    activeIndex = _target;  
                }  
            });  

            /**  
             * 截取url地址,获取窗口的id;  
             * @param {String} url html文件的路径  
             * @param {String} wvId webviewObject的id  
             */  
            function cutWebviewId(url) {  
                var startIndex = url.lastIndexOf("/");  
                var endIndex = url.lastIndexOf(".html");  
                var wvId = url.substring(startIndex   1, endIndex);  
                return wvId;  
            }  
        </script>  
    </body>  

</html>

明确了我们要干什么,我们来看下切换的这个函数:

/**  
 * 切换页面  
 * @param {String} _event 事件类型  
 * @param {Number} _active 当前页面索引  
 * @param {Number} _target 目标页面索引  
 */  
function switchPage(_event, _active, _target) {  
    /**  
     * 目标页面展示  
     * http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewObject.show  
     */  
    subWvs[_target].show("fade-in");  
    // 顶部文字替换  
    title.innerText = labels[_target].innerText;  
    // 如果是滑动事件,则手动切换高亮选项;  
    if(_event == "switch") {  
        tabs[_active].classList.remove("mui-active");  
        tabs[_target].classList.add("mui-active");  
    }  
    // 之前展示的页面隐藏  
    subWvs[_active].hide("none");  
    // 更新当前页索引  
    activeIndex = _target;  
}  

_event代表切的方式,_active代表当前展示的窗口索引,_target代表目标窗口的索引。
首先将目标窗口show出来,然后替换顶部标题的文字内容。然后判定下切的方式,如果是滑动切换,我们需要自己来对classList进行操作,完成选项卡高亮的转换。最后,我们需要把之前展示的选项卡隐藏掉,并且把当前窗口的索引值赋给中间量。
二、sub.js
所有的子页面都引入这个JS文件,内容如下:

mui.init();  
mui.plusReady(function() {  
    // 获取当前窗口对象  
    var self = plus.webview.currentWebview();  
    // 读取传递过来的参数  
    var index = self.index;  
    /**  
     * 获取父窗口对象  
     * http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewObject.parent  
     */  
    var parent = self.parent();  
    // 左滑事件  
    document.addEventListener("swipeleft", function(event) {  
        var angle = event.detail.angle;  
        angle = Math.abs(angle);  
        /**  
         * 控制滑动的角度,为避免误操作,可自定义限制滑动角度;  
         */  
        if(angle > 175 && angle < 185) {  
            parentEvent(parent, index, "left");  
        }  
    });  
    // 右滑事件  
    document.addEventListener("swiperight", function(event) {  
        var angle = event.detail.angle;  
        angle = Math.abs(angle);  
        /**  
         * 控制滑动的角度,为避免误操作,可自定义限制滑动角度;  
         */  
        if(angle < 4) {  
            parentEvent(parent, index, "right");  
        }  
    });  
});  

/**  
 * 触发父窗口自定义事件  
 * @param {Object} wvobj 目标窗口对象  
 * @param {Number} index 索引值  
 * @param {String} direction 方向  
 */  
function parentEvent(wvobj, index, direction) {  
    /**  
     * 触发自定义事件  
     * http://dev.dcloud.net.cn/mui/event/#customevent  
     */  
    mui.fire(wvobj, "swipe_event", {  
        direction: direction,  
        index: index  
    });  
}  

内容简单明了,就是监听左滑和右滑事件,然后去触发父窗口的自定义切换事件。关键点在于event.detail.angle,这个是mui自己封装的一个属性,用来表示滑动的角度(具体的值,大家可以自己滑动时候多测试测试)。大家也可以尝试下,不对滑动角度进行控制,切换会过于灵敏,影响到其他正常的操作。
文笔功力有限,有哪些地方不是很明了,还请见谅,也希望能提出您宝贵的意见,我会继续改进。
最后,附上源码,真机运行即可。

继续阅读 »

关于选项卡切换,相信大家都不陌生。hello mui中提供了多种选项卡切换的实现方式,不过大体分为div模式(单页)以及webviedw模式(多个页面)。div模式中又提供了可左右拖动实现切换的模式,如图:

在实际开发中,数据量只会多不会少,因此我们通常都会采用webview模式选项卡。与此同时,许多同学依旧希望能够实现滑动来实现选项卡的切换。就像这样:

可能大家会说,这个滑动并不是那么灵敏。那是因为我控制的角度范围较小(更加精确方便的范围还在进一步测试),实际开发中大家可以根据自己的需求来修改这个范围。
一、main.html
在主页面,我们需要做许多事情,创建自窗口对象(不然切什么换),底部选项点击切换(这是基本的切换),自定义事件切换(子窗口滑动事件来触发)。
其中关键的地方,在于切换。切换,我们要切什么,换什么这才是选项卡切换的核心。
切,有两种切法,点击和滑动。
换,换子窗口,换标题,换底部高亮文字。

<!doctype html>  
<html>  

    <head>  
        <meta charset="UTF-8">  
        <title></title>  
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />  
        <link href="http://ask.dcloud.net.cn/css/mui.min.css" rel="stylesheet" />  
    </head>  

    <body>  
        <header class="mui-bar mui-bar-nav">  
            <h1 class="mui-title">首页</h1>  
        </header>  
        <nav class="mui-bar mui-bar-tab">  
            <a class="mui-tab-item mui-active" data-index="0">  
                <span class="mui-icon mui-icon-home"></span>  
                <span class="mui-tab-label">首页</span>  
            </a>  
            <a class="mui-tab-item" data-index="1">  
                <span class="mui-icon mui-icon-phone"></span>  
                <span class="mui-tab-label">电话</span>  
            </a>  
            <a class="mui-tab-item" data-index="2">  
                <span class="mui-icon mui-icon-email"></span>  
                <span class="mui-tab-label">邮件</span>  
            </a>  
            <a class="mui-tab-item" data-index="3">  
                <span class="mui-icon mui-icon-gear"></span>  
                <span class="mui-tab-label">设置</span>  
            </a>  
        </nav>  
        <script src="js/mui.min.js"></script>  
        <script type="text/javascript">  
            mui.init();  
            mui.plusReady(function() {  
                /**  
                 * 当前窗口对象,即父窗口;  
                 * http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.currentWebview  
                 */  
                var self = plus.webview.currentWebview();  
                // 子窗口地址数组  
                var subpages = ["home.html", "phone.html", "email.html", "gear.html"];  
                // 子窗口样式  
                var subStyles = {  
                    top: "45px",  
                    bottom: "50px"  
                };  
                // 子窗口数量  
                var subLen = subpages.length;  
                // 子窗口对象数组  
                var subWvs = [];  
                // 标题栏  
                var title = document.querySelector(".mui-title");  
                // 底部选项  
                var tabs = document.querySelectorAll(".mui-tab-item");  
                // 底部文字  
                var labels = document.querySelectorAll(".mui-tab-label");  
                // 当前页面索引,初始化为0;  
                var activeIndex = 0;  
                // 目标页面索引,初始化为当前页面索引;  
                var targetIndex = activeIndex;  
                // 创建子页面  
                for(var i = 0; i < subLen; i  ) {  
                    /**  
                     * 创建窗口对象,并将索引做为额外的参数传递;  
                     * http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.create  
                     */  
                    var subWv = plus.webview.create(subpages[i], cutWebviewId(subpages[i]), subStyles, {  
                        index: i  
                    });  
                    // 窗口对象添加至数组  
                    subWvs.push(subWv);  
                    if(i > 0) {  
                        /**  
                         * 隐藏非第一页的窗口对象  
                         * http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewObject.hide  
                         */  
                        subWv.hide("none");  
                    }  
                    /**  
                     * 向父窗口添加子窗口  
                     * http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewObject.append  
                     */  
                    self.append(subWv);  
                }  
                // 底部选项卡点击切换事件  
                for(var j = 0, jlen = tabs.length; j < jlen; j  ) {  
                    tabs[j].addEventListener("tap", function() {  
                        // 获取当前结点的索引  
                        targetIndex = this.getAttribute("data-index");  
                        // 转换为number类型  
                        targetIndex = parseInt(targetIndex, 10);  
                        if(targetIndex == activeIndex) {  
                            return;  
                        }  
                        // 切换页面  
                        switchPage("tap", activeIndex, targetIndex);  
                    });  
                }  
                // 子页面滑动切换事件  
                window.addEventListener("swipe_event", function(event) {  
                    // 获取方向以及索引  
                    var direction = event.detail.direction;  
                    activeIndex = event.detail.index;  
                    if(direction == "left") {  
                        // 如果是最后一个页面,则不做左滑切换;  
                        if(activeIndex == subLen - 1) {  
                            console.log("最右边一页了");  
                            return;  
                        }  
                        // 目标页面的索引为后面一位  
                        targetIndex = activeIndex   1;  
                    } else {  
                        // 如果是第一个页面,则不做右滑切换;  
                        if(activeIndex == 0) {  
                            console.log("最左边一页了");  
                            return;  
                        }  
                        // 目标页面的索引为前面一位  
                        targetIndex = activeIndex - 1;  
                    }  
                    // 切换页面  
                    switchPage("switch", activeIndex, targetIndex);  
                });  

                /**  
                 * 切换页面  
                 * @param {String} _event 事件类型  
                 * @param {Number} _active 当前页面索引  
                 * @param {Number} _target 目标页面索引  
                 */  
                function switchPage(_event, _active, _target) {  
                    /**  
                     * 目标页面展示  
                     * http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewObject.show  
                     */  
                    subWvs[_target].show("fade-in");  
                    // 顶部文字替换  
                    title.innerText = labels[_target].innerText;  
                    // 如果是滑动事件,则手动切换高亮选项;  
                    if(_event == "switch") {  
                        tabs[_active].classList.remove("mui-active");  
                        tabs[_target].classList.add("mui-active");  
                    }  
                    // 之前展示的页面隐藏  
                    subWvs[_active].hide("none");  
                    // 更新当前页索引  
                    activeIndex = _target;  
                }  
            });  

            /**  
             * 截取url地址,获取窗口的id;  
             * @param {String} url html文件的路径  
             * @param {String} wvId webviewObject的id  
             */  
            function cutWebviewId(url) {  
                var startIndex = url.lastIndexOf("/");  
                var endIndex = url.lastIndexOf(".html");  
                var wvId = url.substring(startIndex   1, endIndex);  
                return wvId;  
            }  
        </script>  
    </body>  

</html>

明确了我们要干什么,我们来看下切换的这个函数:

/**  
 * 切换页面  
 * @param {String} _event 事件类型  
 * @param {Number} _active 当前页面索引  
 * @param {Number} _target 目标页面索引  
 */  
function switchPage(_event, _active, _target) {  
    /**  
     * 目标页面展示  
     * http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewObject.show  
     */  
    subWvs[_target].show("fade-in");  
    // 顶部文字替换  
    title.innerText = labels[_target].innerText;  
    // 如果是滑动事件,则手动切换高亮选项;  
    if(_event == "switch") {  
        tabs[_active].classList.remove("mui-active");  
        tabs[_target].classList.add("mui-active");  
    }  
    // 之前展示的页面隐藏  
    subWvs[_active].hide("none");  
    // 更新当前页索引  
    activeIndex = _target;  
}  

_event代表切的方式,_active代表当前展示的窗口索引,_target代表目标窗口的索引。
首先将目标窗口show出来,然后替换顶部标题的文字内容。然后判定下切的方式,如果是滑动切换,我们需要自己来对classList进行操作,完成选项卡高亮的转换。最后,我们需要把之前展示的选项卡隐藏掉,并且把当前窗口的索引值赋给中间量。
二、sub.js
所有的子页面都引入这个JS文件,内容如下:

mui.init();  
mui.plusReady(function() {  
    // 获取当前窗口对象  
    var self = plus.webview.currentWebview();  
    // 读取传递过来的参数  
    var index = self.index;  
    /**  
     * 获取父窗口对象  
     * http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.WebviewObject.parent  
     */  
    var parent = self.parent();  
    // 左滑事件  
    document.addEventListener("swipeleft", function(event) {  
        var angle = event.detail.angle;  
        angle = Math.abs(angle);  
        /**  
         * 控制滑动的角度,为避免误操作,可自定义限制滑动角度;  
         */  
        if(angle > 175 && angle < 185) {  
            parentEvent(parent, index, "left");  
        }  
    });  
    // 右滑事件  
    document.addEventListener("swiperight", function(event) {  
        var angle = event.detail.angle;  
        angle = Math.abs(angle);  
        /**  
         * 控制滑动的角度,为避免误操作,可自定义限制滑动角度;  
         */  
        if(angle < 4) {  
            parentEvent(parent, index, "right");  
        }  
    });  
});  

/**  
 * 触发父窗口自定义事件  
 * @param {Object} wvobj 目标窗口对象  
 * @param {Number} index 索引值  
 * @param {String} direction 方向  
 */  
function parentEvent(wvobj, index, direction) {  
    /**  
     * 触发自定义事件  
     * http://dev.dcloud.net.cn/mui/event/#customevent  
     */  
    mui.fire(wvobj, "swipe_event", {  
        direction: direction,  
        index: index  
    });  
}  

内容简单明了,就是监听左滑和右滑事件,然后去触发父窗口的自定义切换事件。关键点在于event.detail.angle,这个是mui自己封装的一个属性,用来表示滑动的角度(具体的值,大家可以自己滑动时候多测试测试)。大家也可以尝试下,不对滑动角度进行控制,切换会过于灵敏,影响到其他正常的操作。
文笔功力有限,有哪些地方不是很明了,还请见谅,也希望能提出您宝贵的意见,我会继续改进。
最后,附上源码,真机运行即可。

收起阅读 »