
分享一个多页面倒计时60秒防止刷新的按钮+沉浸式状态栏js
var DA = {
navStyle:function (color){//状态栏样式,参数(颜色),在ios7和android4.0以上有效
plus.navigator.setStatusBarBackground(color);
plus.navigator.setStatusBarStyle('UIStatusBarStyleBlackOpaque')
},
timeInit:function(btn_name){//初始化验证码按钮倒计时状态和设置当前页面的本地存储name
var countdown = localStorage.getItem(''+btn_name+'');
if(countdown == null||countdown == "0"){
$("#code_btn").html("获取验证码");
$("#code_btn").css({'background':'#48A2E0','disabled':false,'color':'#fff'});
localStorage.removeItem(''+btn_name+'');
}else if(countdown !== "0"){
$("#code_btn").css({'background':'#ccc','disabled':true,'color':'#5f5f5f'})
$("#code_btn").html("重新发送 ( " + countdown + " )");
this.timedown(''+btn_name+'');
}
},
timedown:function(btn_name){//倒计时定时器
var countdowns;
countdown = localStorage.getItem(''+btn_name+'');
if (countdown == '0') {
$("#code_btn").html("获取验证码");
$("#code_btn").css({'background':'#48A2E0','disabled':false,'color':'#fff'})
return clearTimeout();//清除定时,没有的话会导致后面每次减一越来越快
} else {
$("#code_btn").html("重新发送 ( " + countdown + " )");
$("#code_btn").css({'background':'#ccc','disabled':true,'color':'#5f5f5f'})
countdown = countdown - 1;
localStorage.setItem(''+btn_name+'',countdown);
}
setTimeout(function() {
DA.timedown(''+btn_name+'')
}, 1000);//定时每秒减一
},
settime:function (btn_name){//点击获取手机号码,判断手机号码,执行此函数
var phone = document.getElementById("phone");//判断是否是input,根据自己的逻辑来玩
if(phone.tagName.toLocaleLowerCase() == 'input'){
var check_phone_number = /^1[3458]\d{9}$/;
if (phone.value.length == '') {
DA.X_toast("手机号不能为空",'error.png',1000)
return;
}
if (phone.value.length != 11) {
DA.X_toast("请输入有效的手机号!",'error.png',1000)
return;
}
if (!phone.value.match(check_phone_number)) {
DA.X_toast("请输入有效的手机号",'error.png',1000)
return;
} else {
//短信发送,根据自己逻辑异步获取验证码
localStorage.setItem(''+btn_name+'','10');
this.timedown(''+btn_name+'');
}
}else{
//短信发送,根据自己逻辑异步获取验证码
localStorage.setItem(''+btn_name+'','10');
this.timedown(''+btn_name+'');
}
}
}
function plusReady(){
// 设置系统状态栏样式为浅色文字
DA.navStyle('#000000');
//localStorage.removeItem('LoginToken')//清除键值对
//localStorage.setItem('LoginToken','123456')//设置键值对
var LoginToken;
//console.log(LoginToken);
$('.content_divs').on('tap',function(){
LoginToken = localStorage.getItem("LoginToken");
var _self = $(this);
var url = _self.attr('data-url');
switch(url)
{
case 'Pay_record_head.html':
DA.open(url,'right');
break;
case 'my_assets_head.html':
DA.open(url,'right');
break;
default:
LoginToken == null?(url = 'login.html',DA.open(url,'right')):DA.open(url,'right');
}
})
}
if(window.plus){
plusReady();
}else{
document.addEventListener("plusready",plusReady,false);
}
var DA = {
navStyle:function (color){//状态栏样式,参数(颜色),在ios7和android4.0以上有效
plus.navigator.setStatusBarBackground(color);
plus.navigator.setStatusBarStyle('UIStatusBarStyleBlackOpaque')
},
timeInit:function(btn_name){//初始化验证码按钮倒计时状态和设置当前页面的本地存储name
var countdown = localStorage.getItem(''+btn_name+'');
if(countdown == null||countdown == "0"){
$("#code_btn").html("获取验证码");
$("#code_btn").css({'background':'#48A2E0','disabled':false,'color':'#fff'});
localStorage.removeItem(''+btn_name+'');
}else if(countdown !== "0"){
$("#code_btn").css({'background':'#ccc','disabled':true,'color':'#5f5f5f'})
$("#code_btn").html("重新发送 ( " + countdown + " )");
this.timedown(''+btn_name+'');
}
},
timedown:function(btn_name){//倒计时定时器
var countdowns;
countdown = localStorage.getItem(''+btn_name+'');
if (countdown == '0') {
$("#code_btn").html("获取验证码");
$("#code_btn").css({'background':'#48A2E0','disabled':false,'color':'#fff'})
return clearTimeout();//清除定时,没有的话会导致后面每次减一越来越快
} else {
$("#code_btn").html("重新发送 ( " + countdown + " )");
$("#code_btn").css({'background':'#ccc','disabled':true,'color':'#5f5f5f'})
countdown = countdown - 1;
localStorage.setItem(''+btn_name+'',countdown);
}
setTimeout(function() {
DA.timedown(''+btn_name+'')
}, 1000);//定时每秒减一
},
settime:function (btn_name){//点击获取手机号码,判断手机号码,执行此函数
var phone = document.getElementById("phone");//判断是否是input,根据自己的逻辑来玩
if(phone.tagName.toLocaleLowerCase() == 'input'){
var check_phone_number = /^1[3458]\d{9}$/;
if (phone.value.length == '') {
DA.X_toast("手机号不能为空",'error.png',1000)
return;
}
if (phone.value.length != 11) {
DA.X_toast("请输入有效的手机号!",'error.png',1000)
return;
}
if (!phone.value.match(check_phone_number)) {
DA.X_toast("请输入有效的手机号",'error.png',1000)
return;
} else {
//短信发送,根据自己逻辑异步获取验证码
localStorage.setItem(''+btn_name+'','10');
this.timedown(''+btn_name+'');
}
}else{
//短信发送,根据自己逻辑异步获取验证码
localStorage.setItem(''+btn_name+'','10');
this.timedown(''+btn_name+'');
}
}
}
function plusReady(){
// 设置系统状态栏样式为浅色文字
DA.navStyle('#000000');
//localStorage.removeItem('LoginToken')//清除键值对
//localStorage.setItem('LoginToken','123456')//设置键值对
var LoginToken;
//console.log(LoginToken);
$('.content_divs').on('tap',function(){
LoginToken = localStorage.getItem("LoginToken");
var _self = $(this);
var url = _self.attr('data-url');
switch(url)
{
case 'Pay_record_head.html':
DA.open(url,'right');
break;
case 'my_assets_head.html':
DA.open(url,'right');
break;
default:
LoginToken == null?(url = 'login.html',DA.open(url,'right')):DA.open(url,'right');
}
})
}
if(window.plus){
plusReady();
}else{
document.addEventListener("plusready",plusReady,false);
}
收起阅读 »

【示例】Android及iOS平台下视频全屏播放时自动横屏的实现
需求明确
视频全屏播放时,屏幕自动旋转为横屏。
此类功能,手机内置浏览器以及UC浏览器等,均有不同的实现。
若需要更多功能的定制,需自行扩展插件。
思路
首先,明确不同平台下的全屏事件,也就是所需监听的全屏变化的事件。
Android和iOS平台下,事件存在较大的差异。
其次,根据实际业务需求,对屏幕方向做出相应的调整。
此例中的处理方式为:
视频全屏,即锁定屏幕为横屏。
视频恢复,则解除屏幕方向的锁定。
具体实现
Android
1.常规处理
监听webkitfullscreenchange事件,并且读取全屏元素,对屏幕方向做出调整。
document.addEventListener('webkitfullscreenchange', function() {
var el = document.webkitFullscreenElement; //获取全屏元素
if(el) {
plus.screen.lockOrientation('landscape'); //锁死屏幕方向为横屏
} else {
plus.screen.unlockOrientation(); //解除屏幕方向的锁定
}
});
2.WebviewStyles.videoFullscreen
HBuilder7.6.3.201612161809更新日志的App项中:
“Android平台优化视频全屏旋转效果,增加WebviewStyles.videoFullscreen控制”
意味着我们可以使用更加方便和性能更高的方法实现该功能
var self = plus.webview.currentWebview();
self.setStyle({
videoFullscreen: 'landscape'
});
iOS
监听video元素的webkitbeginfullscreen与webkitendfullscreen事件,在全屏开始和结束时,对屏幕方向做相应的调整。
// 监听的事件与Android平台有很大区别
videoElem.addEventListener('webkitbeginfullscreen', function() {
plus.screen.lockOrientation('landscape'); //锁死屏幕方向为横屏
});
videoElem.addEventListener('webkitendfullscreen', function() {
// plus.screen.unlockOrientation(); //解除屏幕方向的锁定,但是不一定是竖屏;
plus.screen.lockOrientation('portrait'); //锁死屏幕方向为竖屏
});
相关API
设备屏幕信息
原生窗口设置参数的对象
HTML 5+ SDK 更新日志
涉及全屏播放并且需要打包成原生安装包的开发者请注意:
全屏播放涉及屏幕旋转,在iOS上实现此效果则需要在manifest.json中plus -> distribute -> orientation 节点配置应用支持的方向,默认是只支持竖屏正方向。
"orientation": [
"portrait-primary"
],/*应用支持的方向,portrait-primary:竖屏正方向;portrait-secondary:竖屏反方向;landscape-primary:横屏正方向;landscape-secondary:横屏反方向*/
源码
附上源码,解压后放在App工程中,运行即可。
需求明确
视频全屏播放时,屏幕自动旋转为横屏。
此类功能,手机内置浏览器以及UC浏览器等,均有不同的实现。
若需要更多功能的定制,需自行扩展插件。
思路
首先,明确不同平台下的全屏事件,也就是所需监听的全屏变化的事件。
Android和iOS平台下,事件存在较大的差异。
其次,根据实际业务需求,对屏幕方向做出相应的调整。
此例中的处理方式为:
视频全屏,即锁定屏幕为横屏。
视频恢复,则解除屏幕方向的锁定。
具体实现
Android
1.常规处理
监听webkitfullscreenchange事件,并且读取全屏元素,对屏幕方向做出调整。
document.addEventListener('webkitfullscreenchange', function() {
var el = document.webkitFullscreenElement; //获取全屏元素
if(el) {
plus.screen.lockOrientation('landscape'); //锁死屏幕方向为横屏
} else {
plus.screen.unlockOrientation(); //解除屏幕方向的锁定
}
});
2.WebviewStyles.videoFullscreen
HBuilder7.6.3.201612161809更新日志的App项中:
“Android平台优化视频全屏旋转效果,增加WebviewStyles.videoFullscreen控制”
意味着我们可以使用更加方便和性能更高的方法实现该功能
var self = plus.webview.currentWebview();
self.setStyle({
videoFullscreen: 'landscape'
});
iOS
监听video元素的webkitbeginfullscreen与webkitendfullscreen事件,在全屏开始和结束时,对屏幕方向做相应的调整。
// 监听的事件与Android平台有很大区别
videoElem.addEventListener('webkitbeginfullscreen', function() {
plus.screen.lockOrientation('landscape'); //锁死屏幕方向为横屏
});
videoElem.addEventListener('webkitendfullscreen', function() {
// plus.screen.unlockOrientation(); //解除屏幕方向的锁定,但是不一定是竖屏;
plus.screen.lockOrientation('portrait'); //锁死屏幕方向为竖屏
});
相关API
设备屏幕信息
原生窗口设置参数的对象
HTML 5+ SDK 更新日志
涉及全屏播放并且需要打包成原生安装包的开发者请注意:
全屏播放涉及屏幕旋转,在iOS上实现此效果则需要在manifest.json中plus -> distribute -> orientation 节点配置应用支持的方向,默认是只支持竖屏正方向。
"orientation": [
"portrait-primary"
],/*应用支持的方向,portrait-primary:竖屏正方向;portrait-secondary:竖屏反方向;landscape-primary:横屏正方向;landscape-secondary:横屏反方向*/
源码
附上源码,解压后放在App工程中,运行即可。
收起阅读 »
app开发实战 - 《用户注册、登录》视频教程发布!
app开发实战视频教程 - 《用户注册、登录》视频教程已经发布,持续更新(本周内完结)。完结后发布第三方登录教程。
教程完全免费!观看地址
http://www.hcoder.net/course
还有mui、h5+、新闻客户端实战教程 都在这个页面上,欢迎观看!

app开发实战视频教程 - 《用户注册、登录》视频教程已经发布,持续更新(本周内完结)。完结后发布第三方登录教程。
教程完全免费!观看地址
http://www.hcoder.net/course
还有mui、h5+、新闻客户端实战教程 都在这个页面上,欢迎观看!
收起阅读 »
流应用引擎SDK
流应用引擎SDK是为流应用的发行渠道,如应用市场、浏览器、桌面、语音助手、扫码工具、清理替换、广告sdk、推送sdk等,通过集成DCloud的流应用引擎SDK,可在自己的产品中发行流应用。
每个流应用都有一个唯一的appid,发行渠道集成了流应用引擎SDK后,调起流应用引擎SDK时传入指定的appid,即可启动该流应用。
Android平台流应用引擎SDK
2017-11-30发布
更新日志
- 适配全面屏手机。
- 支持辅助输入。
- 修复在Android7上启动应用闪一下桌面的问题(需将io.dcloud.appstream.StreamAppMainActivity的主题样式设置为"@android:style/Theme.NoDisplay")。
- 同步更新流应用内核:修复一些已知的BUG等。
下载流应用引擎SDK
2017-11-20发布
更新日志
- 修复部分手机沉浸式离线集成无效的问题。
- 修复单页面集成模式下,无法加载远程网页的问题。
- 修复已存在地图页面的情况下,创建打开另一个webview页面只显示空白的问题
- 同步更新流应用内核:修复一些已知的BUG等
下载流应用引擎SDK
IOS平台流应用引擎SDK
流应用引擎SDK是为流应用的发行渠道,如应用市场、浏览器、桌面、语音助手、扫码工具、清理替换、广告sdk、推送sdk等,通过集成DCloud的流应用引擎SDK,可在自己的产品中发行流应用。
每个流应用都有一个唯一的appid,发行渠道集成了流应用引擎SDK后,调起流应用引擎SDK时传入指定的appid,即可启动该流应用。
Android平台流应用引擎SDK
2017-11-30发布
更新日志
- 适配全面屏手机。
- 支持辅助输入。
- 修复在Android7上启动应用闪一下桌面的问题(需将io.dcloud.appstream.StreamAppMainActivity的主题样式设置为"@android:style/Theme.NoDisplay")。
- 同步更新流应用内核:修复一些已知的BUG等。
下载流应用引擎SDK
2017-11-20发布
更新日志
- 修复部分手机沉浸式离线集成无效的问题。
- 修复单页面集成模式下,无法加载远程网页的问题。
- 修复已存在地图页面的情况下,创建打开另一个webview页面只显示空白的问题
- 同步更新流应用内核:修复一些已知的BUG等
下载流应用引擎SDK
IOS平台流应用引擎SDK
收起阅读 »
通讯录获取指定的多人信息
首先我要在这里吐槽一下官方文档和问答!!
官方文档实在是太简陋了,要自己做复杂一点点都要自己去摸索,比如获取到了phoneNumbe之后根本没有说还要写value;birthday出来的是number而不是官网上写的Date类型!文档太多槽点不说了。
问答搜索的时候几乎没有我要的信息!!!几乎没有!!!好吧,没有就算了吧,我发表一下提问,然而没几个人可以回复我,发过四个问题,一个解决了,两个没人回答,一个回答还是让我自己解决了。好吧,没人回答就算了,那我百度一下,没什么内容,几乎都是官网的东西,那我google一下吧,还是一个样!!细节内容实在太少了!!做一些简单的app可以,要说复杂的真的是摸着石头过河啊!!!!
吐槽完毕,希望官方可以好好发展一下资料问题,要是没有很好的一份文档以及社区搜索,真的好难吸引太多人,而且用到一半都快要弃用了。。。性能问题我目前还没用遇到过,性能目前来说还是不错的。
正文如下:
一、获取多个人的信息:要解决通讯录导入多个人的信息之前,要解决获取多个人的信息。我通过plus.contacts.getAddressBook和address.find的套用把通讯录里面的所有联系人的id和displayName获取出来,然后通过自己写的通讯录获取页面显示出来。
1、解决这个问题首先你要自己写一个js通讯录,这样可以把你所有联系人首字母分离出来,并且旁边可以跳转到你要的首字母。
资料可以参考我自己写的JS:http://www.cnblogs.com/claireyu1219/p/6131314.html
也可以参考官方的:http://dcloud.io/hellomui/examples/indexed-list.html
2、解决获取所有联系人信息
plus.contacts.getAddressBook(plus.contacts.ADDRESSBOOK_PHONE, function(addressbook) { //获取通讯录信息
// 可通过addressbook进行通讯录操作
addressbook.find(null, function(contacts) {
var username = new Array();
var LinkList = new LinkedList();
if(contacts.length > 0) { //获取当前通讯录里面所有人
for(var i = 0; i < contacts.length; i ) {
username[i] = contacts[i].displayName "-" contacts[i].id; //连接id和username,为后面筛选最准备
}
//这下面的代码是把所有联系人的信息分类,这就涉及到了自己写的JS页面代码
LinkList = sortPY(username); //把联系人数组分类
//LinkList.show();
createLiCheckBox(LinkList); //分类信息显示至页面,我使用checkBox进行多个联系人选择
}
}, function(e) {
alert("Find contact error: " e.message);
});
}, function(e) {
});
二、从通讯录导入多个选定的个人信息:解决这个问题在先前创建通讯录页面的时候就一定要把联系人的id放在在页面上(使用display隐藏),这样我获取被选中的checkBox的时候就可以直接获取id,并且把这些id放到一个数组里面。再通过plus.contacts.getAddressBook和address.find的套用把这些id的联系人信息筛选出来。
1、解决使用checkBox获取联系人id,这里我使用了JQuery。
//筛选已经被选中的checkbox
$("input:checked").each(function() {
var index = $(this).parent().prev().children('label').text(); //获取id
var name = $(this).parent().prev().children('p').text(); //获取姓名
username.push(name);
usernameIndex.push(index);
});
2、解决把这些index放到find里面进行筛选信息,把特定id下面的联系人信息拿出来
plus.contacts.getAddressBook(plus.contacts.ADDRESSBOOK_PHONE, function(addressbook) { //获取通讯录信息
for(var j = 0; j < username.length; j ) {//循环所选取的联系人,记得循环一定要放在这里,一开始我放在 plus.contacts.getAddressBook外面是错误
addressbook.find(null, function(contacts) {
console.log("进入查询");
for(var i = 0; i < contacts.length; i ) {//无论是否为多个信息,一定要循环数组
console.log("进入循环");
//var id = contacts[i].id;
var displayname = contacts[i].displayName;
var phone = "";
var emails = "";
var dates = "";
var remark = "";
if(contacts[i].phoneNumbers.length > 0) {//这里需要判断是否为空,为空的数组没有index=0;
phone = contacts[i].phoneNumbers[0].value;
} else {
phone = contacts[i].phoneNumbers;
}
if(contacts[i].emails.length > 0) {//这里需要判断是否为空,为空的数组没有index=0;
emails = contacts[i].emails[0].value;
} else {
emails = contacts[i].emails;
}
var dateNum = new Date(contacts[i].birthday);//这里的birthday是number类型!!!官方手册坑爹?
dates = dateNum.getFullYear() "." (dateNum.getMonth() 1) "." dateNum.getDate();
remark = contacts[i].note;
var getContact = {//把所有信息放到一个json里面
contactName: displayname,
sex: "",
department: "",
positions: "",
tel: "",
phone: phone,
eMail: emails,
birthday: dates,
hobby: "",
remark: remark
};
//这下面是我的业务代码了,这里大家可以写自己的信息
//createContactTable(db);
//InsertContact(db, getContact); //多个信息插入有线程安全的问题出现!!!!!!!
}
//console.log(username.length);
}, function(e) {
console.log("查询错误");
}, {
//这里面的筛选非常重要!!!这样才能选出匹配的信息
filter: [{
logic: "or",
field: "id",
value: usernameIndex[j]
}],
multi: false
});
}
}, function(e) {
console.log("打开通讯录错误");
});
通过以上代码就可以获取到了多个联系人的信息,大家可以尝试一下。
首先我要在这里吐槽一下官方文档和问答!!
官方文档实在是太简陋了,要自己做复杂一点点都要自己去摸索,比如获取到了phoneNumbe之后根本没有说还要写value;birthday出来的是number而不是官网上写的Date类型!文档太多槽点不说了。
问答搜索的时候几乎没有我要的信息!!!几乎没有!!!好吧,没有就算了吧,我发表一下提问,然而没几个人可以回复我,发过四个问题,一个解决了,两个没人回答,一个回答还是让我自己解决了。好吧,没人回答就算了,那我百度一下,没什么内容,几乎都是官网的东西,那我google一下吧,还是一个样!!细节内容实在太少了!!做一些简单的app可以,要说复杂的真的是摸着石头过河啊!!!!
吐槽完毕,希望官方可以好好发展一下资料问题,要是没有很好的一份文档以及社区搜索,真的好难吸引太多人,而且用到一半都快要弃用了。。。性能问题我目前还没用遇到过,性能目前来说还是不错的。
正文如下:
一、获取多个人的信息:要解决通讯录导入多个人的信息之前,要解决获取多个人的信息。我通过plus.contacts.getAddressBook和address.find的套用把通讯录里面的所有联系人的id和displayName获取出来,然后通过自己写的通讯录获取页面显示出来。
1、解决这个问题首先你要自己写一个js通讯录,这样可以把你所有联系人首字母分离出来,并且旁边可以跳转到你要的首字母。
资料可以参考我自己写的JS:http://www.cnblogs.com/claireyu1219/p/6131314.html
也可以参考官方的:http://dcloud.io/hellomui/examples/indexed-list.html
2、解决获取所有联系人信息
plus.contacts.getAddressBook(plus.contacts.ADDRESSBOOK_PHONE, function(addressbook) { //获取通讯录信息
// 可通过addressbook进行通讯录操作
addressbook.find(null, function(contacts) {
var username = new Array();
var LinkList = new LinkedList();
if(contacts.length > 0) { //获取当前通讯录里面所有人
for(var i = 0; i < contacts.length; i ) {
username[i] = contacts[i].displayName "-" contacts[i].id; //连接id和username,为后面筛选最准备
}
//这下面的代码是把所有联系人的信息分类,这就涉及到了自己写的JS页面代码
LinkList = sortPY(username); //把联系人数组分类
//LinkList.show();
createLiCheckBox(LinkList); //分类信息显示至页面,我使用checkBox进行多个联系人选择
}
}, function(e) {
alert("Find contact error: " e.message);
});
}, function(e) {
});
二、从通讯录导入多个选定的个人信息:解决这个问题在先前创建通讯录页面的时候就一定要把联系人的id放在在页面上(使用display隐藏),这样我获取被选中的checkBox的时候就可以直接获取id,并且把这些id放到一个数组里面。再通过plus.contacts.getAddressBook和address.find的套用把这些id的联系人信息筛选出来。
1、解决使用checkBox获取联系人id,这里我使用了JQuery。
//筛选已经被选中的checkbox
$("input:checked").each(function() {
var index = $(this).parent().prev().children('label').text(); //获取id
var name = $(this).parent().prev().children('p').text(); //获取姓名
username.push(name);
usernameIndex.push(index);
});
2、解决把这些index放到find里面进行筛选信息,把特定id下面的联系人信息拿出来
plus.contacts.getAddressBook(plus.contacts.ADDRESSBOOK_PHONE, function(addressbook) { //获取通讯录信息
for(var j = 0; j < username.length; j ) {//循环所选取的联系人,记得循环一定要放在这里,一开始我放在 plus.contacts.getAddressBook外面是错误
addressbook.find(null, function(contacts) {
console.log("进入查询");
for(var i = 0; i < contacts.length; i ) {//无论是否为多个信息,一定要循环数组
console.log("进入循环");
//var id = contacts[i].id;
var displayname = contacts[i].displayName;
var phone = "";
var emails = "";
var dates = "";
var remark = "";
if(contacts[i].phoneNumbers.length > 0) {//这里需要判断是否为空,为空的数组没有index=0;
phone = contacts[i].phoneNumbers[0].value;
} else {
phone = contacts[i].phoneNumbers;
}
if(contacts[i].emails.length > 0) {//这里需要判断是否为空,为空的数组没有index=0;
emails = contacts[i].emails[0].value;
} else {
emails = contacts[i].emails;
}
var dateNum = new Date(contacts[i].birthday);//这里的birthday是number类型!!!官方手册坑爹?
dates = dateNum.getFullYear() "." (dateNum.getMonth() 1) "." dateNum.getDate();
remark = contacts[i].note;
var getContact = {//把所有信息放到一个json里面
contactName: displayname,
sex: "",
department: "",
positions: "",
tel: "",
phone: phone,
eMail: emails,
birthday: dates,
hobby: "",
remark: remark
};
//这下面是我的业务代码了,这里大家可以写自己的信息
//createContactTable(db);
//InsertContact(db, getContact); //多个信息插入有线程安全的问题出现!!!!!!!
}
//console.log(username.length);
}, function(e) {
console.log("查询错误");
}, {
//这里面的筛选非常重要!!!这样才能选出匹配的信息
filter: [{
logic: "or",
field: "id",
value: usernameIndex[j]
}],
multi: false
});
}
}, function(e) {
console.log("打开通讯录错误");
});
通过以上代码就可以获取到了多个联系人的信息,大家可以尝试一下。
收起阅读 »
图片组件 : 单选 多选 预览 删除 数量限制;录音组件 :录音展示 删除 数量限制
媒体列表组件
图片:单选 多选 预览 删除 数量限制
录音:录音展示 删除 数量限制
<body>
<div id="imgList"></div>
<div id="audioList"></div>
<script src="js/mui.min.js"></script>
<script type="text/javascript" src="js/md5.min.js" ></script>
<script src="js/mui.zoom.js"></script>
<script src="js/mui.previewimage.js"></script>
<script type="text/javascript" src="js/media_components.js" ></script>
<script type="text/javascript">
mui.init({
gestureConfig: {
longtap: true, //默认为false
hold: true, //默认为false,不监听
release: true //默认为false,不监听
}
});
mui.plusReady(function() {
mui('#imgList').imageListInit({
size:5
});
mui('#audioList').audioListInit({
size:5
});
});
</script>
</body>
详细案例见附件
媒体列表组件
图片:单选 多选 预览 删除 数量限制
录音:录音展示 删除 数量限制
<body>
<div id="imgList"></div>
<div id="audioList"></div>
<script src="js/mui.min.js"></script>
<script type="text/javascript" src="js/md5.min.js" ></script>
<script src="js/mui.zoom.js"></script>
<script src="js/mui.previewimage.js"></script>
<script type="text/javascript" src="js/media_components.js" ></script>
<script type="text/javascript">
mui.init({
gestureConfig: {
longtap: true, //默认为false
hold: true, //默认为false,不监听
release: true //默认为false,不监听
}
});
mui.plusReady(function() {
mui('#imgList').imageListInit({
size:5
});
mui('#audioList').audioListInit({
size:5
});
});
</script>
</body>
详细案例见附件
收起阅读 »
app开发视频教程汇总 另感谢dcloud送的显示器
hui 最新版本 1.1.9已经发布
更新内容:
1、优化基础css
2、改进轮播组件(更灵活的配置)
3、改进tab选项卡
4、增加popoverMsg组件
5、修正animate动画
6、增加picker 组件
非常好用 越来越完善的 ui框架(ui组件30+, dom操作方法 20+),更新及时,反馈迅速,欢迎使用!
http://www.hcoder.net/hui
app开发学习资料汇总:
mui、h5+教程、app新闻客户端实战教程、iconfont使用教程、开放数据源尽在hcoder
http://www.hcoder.net
本周内完成app开发用户登录、注册视频教程录制并发布敬请关注!
hcoder在的dcloud官方举报的比赛中获得一等奖(三星曲面显示器)目前已经收到奖品,并在qq群内发了红包!
感谢dcloud!提供给我们国内最优秀的编辑器,最便捷的app开发方式。
hui 最新版本 1.1.9已经发布
更新内容:
1、优化基础css
2、改进轮播组件(更灵活的配置)
3、改进tab选项卡
4、增加popoverMsg组件
5、修正animate动画
6、增加picker 组件
非常好用 越来越完善的 ui框架(ui组件30+, dom操作方法 20+),更新及时,反馈迅速,欢迎使用!
http://www.hcoder.net/hui
app开发学习资料汇总:
mui、h5+教程、app新闻客户端实战教程、iconfont使用教程、开放数据源尽在hcoder
http://www.hcoder.net
本周内完成app开发用户登录、注册视频教程录制并发布敬请关注!
hcoder在的dcloud官方举报的比赛中获得一等奖(三星曲面显示器)目前已经收到奖品,并在qq群内发了红包!
感谢dcloud!提供给我们国内最优秀的编辑器,最便捷的app开发方式。

ios蓝牙打印机插件分享
https://github.com/hennychen/HPrinter.git
如果可以用到,请帮忙资助下谢谢!
https://github.com/hennychen/HPrinter.git
如果可以用到,请帮忙资助下谢谢!

推送android和ios的坑(个推)
最近做的app中使用到了推送,现在把一些踩过的坑跟大家分享下!
我先描述下,我要求的推送效果:app不管在线还是离线,系统通知栏中都显示消息,点击消息按照消息里的要求打开指定页面显示内容。
一、注册个推,填写appid等,这就不说了;确保安卓系统中app的push进程没有被安全软件杀死。
二、推送模板:个推的模板有好几个,为了能给安卓和ios都能推送,只能选择透传消息模板。
三、测试推送消息
你配置的推送必须要打包之后才有效
配置搞定之后最好用推送平台推送一下消息如果都OK(IOS离线在线都可以)如果IOS不行最大的问题是你的IOS的推送证书有问题你需要自己检查了
1.获取设备标示(在demo的push页面有方法)
四、官方给了一种标准和非标准的推送格式。标准的是{title:'标题',content:'内容',payload:'数据'}非标准就是不前面的格式。应用在前台透传消息是不会再显示在通知栏中的。(如果一定要的话就需要在监听透传消息的方法里自己调用创建本地推送的方法plus.push.createMessage(str, jsonData, options))。
1.android:应用在前台会直接收到透传然后自己去处理。
后台不杀死push进程收到透传就去创建本地推送在通知栏显示plus.push.createMessage(str, jsonData, options)
杀死push进程什么也收不到了。当再次打开应用会收到之前的推送。(问了官方说android杀死应用就是收不到郁闷)
android开启了自启模式然而并没有什么卵用。
2.ios:应用在前台会直接收到透传然后自己去处理。
应用关闭和在后台就需要将消息推送个APNS然后APNS在推送给ios手机。(如果后台和关闭状态收不到推送就有可能是 ios的正式配置有问题 你需要一个ios的哥们帮你了)。
3.在创建本地推送并想去你想跳转的页面。那么ios和android就会有少许不同。(巨坑这个需要根据你们自己推送消息定)
这个我需要发送的推送消息格式
{"e":"adsfasdfasf","eid":"afdasdfasf","params":{"xxx":"1231","ccccc":"222222"}}。
4.android的push监听可以写很多都没事而ios你写了它会多次调用push监听方法。多次调用处理方法 这个只能自己一点一点的根据推送的消息格式和数据去处理.
五、测试推送格式和之后处理的一些方法(图1)
1.获取设备标示(在demo的push页面有方法)
2.你每次测试推送不可能都打包测试消息格式这样太浪费时间不现实,有一个比较好的方法将demo的push页面中的发送"透传数据"消息
requireTranMsg();找到打印出url之后在控制台输出地址复制到网页中打开会出现一个透传的模版。之后你就更新里面消息格式就可以了。(如果没问题的在打包测试推送由后端发来的消息)
3.同一手机有用,换手机需要重新来过。
声明一下啊ApiConfig.staticToast("点击本地创建消息启动:");是我写的一个工具类就是打印日志信息 需要的单独加我吧
图2是我自己封装js文件 有网络请求 推送 存储 扫码 定位 支付 上传图片并压缩 微信分享 app下载更新 native获取android的权限
推送只需要在main页面做一次监听其他页面都可以用了
pushUtil.pushListener();
pushUtil.cancelPushClear();
//下面是push推送封装的js文件
var Push = function() {
}
/**
*
* 推送的监听
*/
Push.prototype.pushListener = function () {
var _this = this;
//点击通知监听
plus.push.addEventListener("click", function (msg) {
switch (msg.payload) {
case "LocalMSG":
ApiConfig.staticToast("点击本地创建消息启动:");
break;
default:
ApiConfig.staticToast("点击离线推送消息启动:");
break;
}
if (msg.payload) {
_this.handle(msg);
}
}, false);
//透传监听
plus.push.addEventListener("receive", function (msg) {
if (msg.aps) { // Apple APNS message
ApiConfig.staticToast("接收到在线APNS消息:");
} else {
ApiConfig.staticToast("接收到在线透传消息:");
}
if (plus.os.name == 'iOS') {
if (msg.payload) {
_this.notificationMessage(msg);
}
} else {
_this.notificationMessage(msg);
}
}, false);
}
/**
* 根据推送消息在通知栏中显现对应的提示
* @param {Object} msg
*/
Push.prototype.notificationMessage = function(msg) {
ApiConfig.staticToast(msg, 1);
ApiConfig.staticIsDebug("notificationMessage", msg, 1);
var content = '';//你要展示的提示
var _this = this;
var jsonData = '';
switch(plus.os.name) {
case "Android":
jsonData = eval("(" + msg.payload + ")");
break;
case "iOS":
jsonData = msg.payload;
break;
}
_this.createLocalPushMsg(msg, content);
}
/**
* 处理透传消息
* @param {Object} msg
* @param {Object} content
*/
Push.prototype.createLocalPushMsg = function(msg, content) {
//创建一个符合你自己要显示推送通知
_this.createMessage(str, jsonData, options);
}
/**
* 创建本地推送消息
* @param {Object} content
* @param {Object} payload
* @param {Object} options
*/
Push.prototype.createMessage = function(content, payload, options) {
switch(plus.os.name) {
case "Android":
payload = payload;
break;
case "iOS":
payload = payload.eid;
break;
}
plus.push.createMessage(content, payload, options);
content: ( String ) 必选
消息显示的内容,在系统通知中心中显示的文本内容。
payload: ( String ) 可选
消息承载的数据,可根据业务逻辑自定义数据格式。
options: ( MessageOptions ) 可选
创建消息的额外参数,参考MessageOptions。
}
/**
* 处理通知方法
* @param {Object} msg
*/
Push.prototype.handle = function (msg) {
var _this = this;
//获取到某个页面的参数
var aaa = plus.webview.getWebviewById('xxxxx');
//打印日志的不需要管 当成console.log
ApiConfig.staticIsDebug("msg", msg, 1);
var jsonData = '';
//判断机型是那种 这需要处理一下 Android过来是字符串类型 在这个转换成json格式的数据 ios是对象
switch (plus.os.name) {
case "Android":
jsonData = eval("(" + msg.payload + ")");
break;
case "iOS":
//aps是apns的属于app应用离线和再后台情况
if (msg.aps) {
try {
jsonData = msg.payload;
} catch (e) {
}
} else {
//app再前台的情况
jsonData = msg.payload;
}
break;
}
var openUrl = '';//打开的webView的地址
var openId = '';//创建webView的唯一id标识
//根据你的推送类型去判断单独处理或者跳转到某个页面
switch (jsonData.e) {
case 'xxxx':
break;
case 'aaaa':
break;
case 'bbbb':
break;
case 'ccccc':
break;
default:
break;
}
//跳转的方法
_this.openUrlParams(openUrl, openId, params);
//需要回调的业务去刷新 比如你再订单详情支付完成之后去刷新订单列表页面的方法
//aaa是刷新的那个页面的参数 Refresh是刷新的函数 params你可能需要的参数
mui.fire(aaa, 'Refresh', params);
//写在回调的那个页面
window.addEventListener('Refresh', function () {
//pulldownRefresh();
//具体业务逻辑
});
//处理推送的小红点
this.cancelPushclear();
}
/**
*跳转相应的页面
* @param {Object} openUrl
* @param {Object} openId
* @param {Object} params
*/
Push.prototype.openUrlParams = function (openUrl, openId, params) {
utilsJs.openWebView(openUrl, openId, params);
}
Push.prototype.cancelPushClear = function () {
plus.push.clear();
}
/**
* utilsJs.openWebView(openUrl, openId, params);
* 封装mui.openWindow方法
* @param {Object} openUrl String
* @param {Object} openId String
* @param {Object} params 对象
*/
Utils.prototype.openWebView = function (openUrl, openId, params) {
//关闭右滑关闭
// styles: {
// popGesture: 'none'
// },
if (openUrl && openId) {
mui.openWindow({
url: openUrl,
id: openId,
popGesture: 'close',
extras: params,
createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示
show: {
autoShow: true, //页面loaded事件发生后自动显示,默认为true
aniShow: "slide-in-right" //页面显示动画,默认为”slide-in-right“;
},
waiting: {
autoShow: true, //自动显示等待框,默认为true
title: '正在加载...' //等待对话框上显示的提示内容
}
});
} else {
ApiConfig.staticShowToast('请求参数有问题!');
}
}
此代码仅适用html5+不适用混编,几个月前写的可能有一些遗漏地方,如果有误请指正。qq:934834037
附上源码链接
最近做的app中使用到了推送,现在把一些踩过的坑跟大家分享下!
我先描述下,我要求的推送效果:app不管在线还是离线,系统通知栏中都显示消息,点击消息按照消息里的要求打开指定页面显示内容。
一、注册个推,填写appid等,这就不说了;确保安卓系统中app的push进程没有被安全软件杀死。
二、推送模板:个推的模板有好几个,为了能给安卓和ios都能推送,只能选择透传消息模板。
三、测试推送消息
你配置的推送必须要打包之后才有效
配置搞定之后最好用推送平台推送一下消息如果都OK(IOS离线在线都可以)如果IOS不行最大的问题是你的IOS的推送证书有问题你需要自己检查了
1.获取设备标示(在demo的push页面有方法)
四、官方给了一种标准和非标准的推送格式。标准的是{title:'标题',content:'内容',payload:'数据'}非标准就是不前面的格式。应用在前台透传消息是不会再显示在通知栏中的。(如果一定要的话就需要在监听透传消息的方法里自己调用创建本地推送的方法plus.push.createMessage(str, jsonData, options))。
1.android:应用在前台会直接收到透传然后自己去处理。
后台不杀死push进程收到透传就去创建本地推送在通知栏显示plus.push.createMessage(str, jsonData, options)
杀死push进程什么也收不到了。当再次打开应用会收到之前的推送。(问了官方说android杀死应用就是收不到郁闷)
android开启了自启模式然而并没有什么卵用。
2.ios:应用在前台会直接收到透传然后自己去处理。
应用关闭和在后台就需要将消息推送个APNS然后APNS在推送给ios手机。(如果后台和关闭状态收不到推送就有可能是 ios的正式配置有问题 你需要一个ios的哥们帮你了)。
3.在创建本地推送并想去你想跳转的页面。那么ios和android就会有少许不同。(巨坑这个需要根据你们自己推送消息定)
这个我需要发送的推送消息格式
{"e":"adsfasdfasf","eid":"afdasdfasf","params":{"xxx":"1231","ccccc":"222222"}}。
4.android的push监听可以写很多都没事而ios你写了它会多次调用push监听方法。多次调用处理方法 这个只能自己一点一点的根据推送的消息格式和数据去处理.
五、测试推送格式和之后处理的一些方法(图1)
1.获取设备标示(在demo的push页面有方法)
2.你每次测试推送不可能都打包测试消息格式这样太浪费时间不现实,有一个比较好的方法将demo的push页面中的发送"透传数据"消息
requireTranMsg();找到打印出url之后在控制台输出地址复制到网页中打开会出现一个透传的模版。之后你就更新里面消息格式就可以了。(如果没问题的在打包测试推送由后端发来的消息)
3.同一手机有用,换手机需要重新来过。
声明一下啊ApiConfig.staticToast("点击本地创建消息启动:");是我写的一个工具类就是打印日志信息 需要的单独加我吧
图2是我自己封装js文件 有网络请求 推送 存储 扫码 定位 支付 上传图片并压缩 微信分享 app下载更新 native获取android的权限
推送只需要在main页面做一次监听其他页面都可以用了
pushUtil.pushListener();
pushUtil.cancelPushClear();
//下面是push推送封装的js文件
var Push = function() {
}
/**
*
* 推送的监听
*/
Push.prototype.pushListener = function () {
var _this = this;
//点击通知监听
plus.push.addEventListener("click", function (msg) {
switch (msg.payload) {
case "LocalMSG":
ApiConfig.staticToast("点击本地创建消息启动:");
break;
default:
ApiConfig.staticToast("点击离线推送消息启动:");
break;
}
if (msg.payload) {
_this.handle(msg);
}
}, false);
//透传监听
plus.push.addEventListener("receive", function (msg) {
if (msg.aps) { // Apple APNS message
ApiConfig.staticToast("接收到在线APNS消息:");
} else {
ApiConfig.staticToast("接收到在线透传消息:");
}
if (plus.os.name == 'iOS') {
if (msg.payload) {
_this.notificationMessage(msg);
}
} else {
_this.notificationMessage(msg);
}
}, false);
}
/**
* 根据推送消息在通知栏中显现对应的提示
* @param {Object} msg
*/
Push.prototype.notificationMessage = function(msg) {
ApiConfig.staticToast(msg, 1);
ApiConfig.staticIsDebug("notificationMessage", msg, 1);
var content = '';//你要展示的提示
var _this = this;
var jsonData = '';
switch(plus.os.name) {
case "Android":
jsonData = eval("(" + msg.payload + ")");
break;
case "iOS":
jsonData = msg.payload;
break;
}
_this.createLocalPushMsg(msg, content);
}
/**
* 处理透传消息
* @param {Object} msg
* @param {Object} content
*/
Push.prototype.createLocalPushMsg = function(msg, content) {
//创建一个符合你自己要显示推送通知
_this.createMessage(str, jsonData, options);
}
/**
* 创建本地推送消息
* @param {Object} content
* @param {Object} payload
* @param {Object} options
*/
Push.prototype.createMessage = function(content, payload, options) {
switch(plus.os.name) {
case "Android":
payload = payload;
break;
case "iOS":
payload = payload.eid;
break;
}
plus.push.createMessage(content, payload, options);
content: ( String ) 必选
消息显示的内容,在系统通知中心中显示的文本内容。
payload: ( String ) 可选
消息承载的数据,可根据业务逻辑自定义数据格式。
options: ( MessageOptions ) 可选
创建消息的额外参数,参考MessageOptions。
}
/**
* 处理通知方法
* @param {Object} msg
*/
Push.prototype.handle = function (msg) {
var _this = this;
//获取到某个页面的参数
var aaa = plus.webview.getWebviewById('xxxxx');
//打印日志的不需要管 当成console.log
ApiConfig.staticIsDebug("msg", msg, 1);
var jsonData = '';
//判断机型是那种 这需要处理一下 Android过来是字符串类型 在这个转换成json格式的数据 ios是对象
switch (plus.os.name) {
case "Android":
jsonData = eval("(" + msg.payload + ")");
break;
case "iOS":
//aps是apns的属于app应用离线和再后台情况
if (msg.aps) {
try {
jsonData = msg.payload;
} catch (e) {
}
} else {
//app再前台的情况
jsonData = msg.payload;
}
break;
}
var openUrl = '';//打开的webView的地址
var openId = '';//创建webView的唯一id标识
//根据你的推送类型去判断单独处理或者跳转到某个页面
switch (jsonData.e) {
case 'xxxx':
break;
case 'aaaa':
break;
case 'bbbb':
break;
case 'ccccc':
break;
default:
break;
}
//跳转的方法
_this.openUrlParams(openUrl, openId, params);
//需要回调的业务去刷新 比如你再订单详情支付完成之后去刷新订单列表页面的方法
//aaa是刷新的那个页面的参数 Refresh是刷新的函数 params你可能需要的参数
mui.fire(aaa, 'Refresh', params);
//写在回调的那个页面
window.addEventListener('Refresh', function () {
//pulldownRefresh();
//具体业务逻辑
});
//处理推送的小红点
this.cancelPushclear();
}
/**
*跳转相应的页面
* @param {Object} openUrl
* @param {Object} openId
* @param {Object} params
*/
Push.prototype.openUrlParams = function (openUrl, openId, params) {
utilsJs.openWebView(openUrl, openId, params);
}
Push.prototype.cancelPushClear = function () {
plus.push.clear();
}
/**
* utilsJs.openWebView(openUrl, openId, params);
* 封装mui.openWindow方法
* @param {Object} openUrl String
* @param {Object} openId String
* @param {Object} params 对象
*/
Utils.prototype.openWebView = function (openUrl, openId, params) {
//关闭右滑关闭
// styles: {
// popGesture: 'none'
// },
if (openUrl && openId) {
mui.openWindow({
url: openUrl,
id: openId,
popGesture: 'close',
extras: params,
createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示
show: {
autoShow: true, //页面loaded事件发生后自动显示,默认为true
aniShow: "slide-in-right" //页面显示动画,默认为”slide-in-right“;
},
waiting: {
autoShow: true, //自动显示等待框,默认为true
title: '正在加载...' //等待对话框上显示的提示内容
}
});
} else {
ApiConfig.staticShowToast('请求参数有问题!');
}
}
此代码仅适用html5+不适用混编,几个月前写的可能有一些遗漏地方,如果有误请指正。qq:934834037
附上源码链接

在mac上远程链接windows
今天在用mac远程链接windows电脑的时候,以为很简单,结果一不小心却掉进了坑里。
window自带的mstsc没办法用,于是转战https://www.microsoft.com/zh-CN/download/confirmation.aspx?id=18140
下载了 Microsoft 适用于 Mac 的远程桌面连接客户端 2.1.1
一切都很顺利,结果在链接的时候却出现了
,无奈访遍各大论坛发现我的mac是sierra,依旧无法解决问题,突然,转机出现了,在mac store 下载 parallels client
这个软件,免费的,填好ip,填上用户名和密码,完美的解决了我的问题!!!那个激动啊!
今天在用mac远程链接windows电脑的时候,以为很简单,结果一不小心却掉进了坑里。
window自带的mstsc没办法用,于是转战https://www.microsoft.com/zh-CN/download/confirmation.aspx?id=18140
下载了 Microsoft 适用于 Mac 的远程桌面连接客户端 2.1.1
一切都很顺利,结果在链接的时候却出现了
,无奈访遍各大论坛发现我的mac是sierra,依旧无法解决问题,突然,转机出现了,在mac store 下载 parallels client
这个软件,免费的,填好ip,填上用户名和密码,完美的解决了我的问题!!!那个激动啊! 收起阅读 »

获取首页id和webview
如何获取webview的id?
情况是这样的,启动加载的第一个页面index.html,没有设置id,url等,如何在其它页面获取index.html页面的webview?
或者告知如何为一个页面设置id,应用启动时设置的哪个页面的id?
方法如下:
获取首页id plus.runtime.appid;
首页webview plus.webview.getLaunchWebview();
如何获取webview的id?
情况是这样的,启动加载的第一个页面index.html,没有设置id,url等,如何在其它页面获取index.html页面的webview?
或者告知如何为一个页面设置id,应用启动时设置的哪个页面的id?
方法如下:
获取首页id plus.runtime.appid;
首页webview plus.webview.getLaunchWebview();