ApiCloud
一、config.xml配置文件
<widget id="A12345678901" version="0.0.1"> <name>API Example</name> <description> API Example App. </description> <author email="developer@apicloud.com" href="http://www.apicloud.com"> APICloud.SIR </author> <content src="index.html" /> <access origin="*" /> <preference name="windowBackground" value="#FFF" /> <permission name="call" /> <feature name="weiXin"> <param name="urlScheme" value="wx7779c7c063a9d4d9" /> </feature> </widget>
- “id”: 必填,应用ID,由云服务器自动分配。它是该应用的唯一标识。
- “version”:必填,应用的版本号。
- “name”:必填,应用名称。
- “description”:可选,应用简单描述信息。
- “content”:必填,应用运行的起始页。
- “permission”:必填,权限配置。 (详细介绍见应用配置指南文档)
二、模块调用
var dialogBox; apiready = function() { dialogBox = api.require('dialogBox'); }
三、属性
1,tapmode
tapmode具有速点击事件功能,在触发事件中加入tapmode可以消除JS中标准click事件的300毫秒延迟;同时,它具有触发可显示样式的效果,tapmode='css样式类' 属性,当该元素touchstart touchmove的时候就会展现css样式。
<div tapmode onclick="aa()">点击我tapmode</div> function aa() { alert("aa"); }
四、方法
1,parseTapmode
api.parseTapmode()
若是之后用代码创建的 dom 元素,则需要调用该方法后 tapmode 属性才会生效
!!!注意!!!:引擎对具有tapmode属性的元素点击事件的优化处理会在apiready事件触发之前,根据当前的dom树自动进行优化。在apiready之后加载的数据使用要显式的调用api.parseTapmode方法来进行主动的tapmode处理,例如在上拉加载更多数据后,要调用一下api.parseTapmode方法.
!!!注意!!!:要按UE设计确定可点击区域的大小,可以适当扩大点击区域来保障点击反应的灵敏。
!!!注意!!!:api.parseTapmode调用会有性能成本,不需要的情况下不要随便调用。
!!!注意!!!:要按照需求明确所有按钮点击时的交互效果,为tapmode属性设置正确的样式值,对于没有交互效果的点击实现,可以不为tapmode属性指定任何样式,但是为了优化点击速度,必须要给元素增加tapmode属性。
2,fixStatusBar
传入的DOM元素增加适当的上内边距,避免header与状态栏重叠
var header = $api.byId('aui-header');
if (header) {
$api.fixStatusBar(header);
}
无法跟config.xml里面的 <preference name="statusBarAppearance" value="false" /> 一起使用
3,setStorage/getStorage
//设置
$api.setStorage('user', {name:'hunter',sex:'男'});
//获取
var user=$api.getStorage('user');
var str= "姓名:"+user.name+";性别:"+user.sex;
4,JSON
JSON.parse(‘’) 方法用于将一个 JSON 字符串转换为对象
JSON.stringify(data) 方法是将一个JavaScript值(对象或者数组)转换为一个 JSON字符串
5,win/frm传参
//传入参数 api.openWin({ name: 'prodetail_win', url: 'project/prodetail_win.html', pageParam: { prj_id: id } }); 接收参数 api.pageParam
6,上传文件
function fnUpload(filepath, callback) { var files = []; if (typeof(filepath) == 'string') { files.push(filepath); } else { files = filepath } api.ajax({ url: webpage + '/api/Sys/UploadFile', method: 'post', data: { files: { 'headimg': files } } }, function(ret, err) { if (ret) { if (checktoken(ret.ret)) { if (ret.ret == 0) { callback(ret); } else { alertmsg(ret.msg); } } } else { errormsg(err); } }); };
getOneImg('camera', 'url', function(result) { var url = result.data; fnUpload(url,function(res){ if(res.ret==0)VM.imgUrls.push(res.data) }) //gouploadfile(url, dirpid); });
7,调用相机或图库
function getOneImg(sourceType, destinationType, callback) { var quality = 80; var targetWidth = 800; var targetHeight = 800; if (api.systemType == 'ios') { quality = 50; targetWidth = 500; targetHeight = 500; } api.getPicture({ sourceType: sourceType, encodingType: 'jpg', mediaValue: 'pic', destinationType: destinationType, quality: quality, targetWidth: targetWidth, targetHeight: targetHeight }, function(ret, err) { if (ret) { if (ret.data) { callback(ret); } else { api.toast({ msg: '取消选择' }); } } else { if (err.msg === 'user canceled') { api.toast({ msg: '取消选择' }); } else { api.toast({ msg: '读取图片错误' }); } } }); }
8,多图选择
//多图选择 function getImgsObj(max, callback) { var UIAlbumBrowser = api.require('UIAlbumBrowser'); var fcolor = '#fff'; if (api.systemType == 'ios') { fcolor = '#000'; } UIAlbumBrowser.open({ max: max, type: 'image', styles: { bg: '#fff', mark: { icon: '', position: 'bottom_left', size: 20 }, nav: { bg: '#03a9f4', titleColor: '#fff', titleSize: 18, cancelColor: '#fff', cancelSize: 16, finishColor: fcolor, finishSize: 16 } }, rotation: true }, function(ret) { if (ret) { if (ret.eventType == 'confirm') { if (!ret.list || ret.list.length <= 0) return; callback(ret); } } }); }
//多图上传 getImgsObj(5, function(res) { showProgressMsg('图片处理中'); var index=0; var total=res.list.length; if(api.systemType=="ios") { for(var i=0;i<total;i++) { var UIAlbumBrowser = api.require('UIAlbumBrowser'); UIAlbumBrowser.transPath({ path: res.list[i].path, scale: 0.1 //图片压缩 0~1.0 }, function(rett, errr) { if (rett) { fnUpload(rett.path,function(resss){ if(resss.ret==0)VM.imgUrls.push(resss.data); if(++index==total)api.hideProgress(); }) } else { } }); } } else { for(var i=0;i<res.list.length;i++) { fnUpload(res.list[i].path,function(resss){ if(resss.ret==0)VM.imgUrls.push(resss.data); //if(++index==total)api.hideProgress(); }) } } });
五、AUI
1,aui-img-round设置图片为圆形
<img src="../../image/2.0/scurity-yx.png" class="aui-img-round aui-list-img-sm">
2,栅格系统
<div class="aui-content aui-content-padded"> <div class="aui-row aui-row-padded"> <div class="aui-col-xs-2">1</div> <div class="aui-col-xs-2">2</div> <div class="aui-col-xs-2">3</div> <div class="aui-col-xs-2">4</div> </div> </div>
3,表单
<div class="aui-content aui-margin-b-15"> <ul class="aui-list aui-form-list"> <li class="aui-list-header">基本信息</li> <li class="aui-list-item"> <div class="aui-list-item-inner"> <div class="aui-list-item-label"> 检查项目 </div> <div class="aui-list-item-input"> <select> <option>上海瓯云总部</option> <option>绿地集团</option> </select> </div> </div> </li> <li class="aui-list-item"> <div class="aui-list-item-inner"> <div class="aui-list-item-label"> 检查部件 </div> <div class="aui-list-item-input"> <select> <option>起重机1号</option> </select> </div> </div> </li> </ul> </div>
4,右边的图片加文字
<div class="aui-pull-right aui-list-item-media" style="width:100px;display:flex;align-items: center;justify-content: center;"> <img src="../../image/2.0/saomiao.png" style="width: 1.2rem" class="aui-list-img-sm" />开始扫描 </div>
5,图片文字一起居中
.box{ display:flex; align-items: center;//子元素垂直居中 justify-content: center;//子元素水平居中 }
6,加上>箭头
<div class="aui-list-item-inner aui-list-item-arrow"> <div class="aui-list-item-label"> 子领域 </div> <div class="aui-list-item-input"> <select v-model="frmData.subdoman" tapmodel onchange="getZgxwt()"> <option v-for="item in subDomains" v-bind:value="item.id">{{item.content}}</option> </select> </div> </div>
<li class="aui-list-item" onclick="add('contacts')"> <div class="aui-list-item-label-icon"> <i class="aui-iconfont aui-icon-mobile"></i> </div> <div class="aui-list-item-inner aui-list-item-arrow"> <div class="aui-list-item-title">选择手机联系人</div> <div class="aui-list-item-right">无需审核</div> </div> </li>
7,图片加圆形边框
<img src="../../image/demo5.png" class="aui-img-round aui-list-img-sm">
六、第三方插件
1,datetime
插件下载:https://pan.baidu.com/s/18fG4M3k72PEPUEE-9e4QCg
<link rel="stylesheet" type="text/css" href="../../script/datetime/mobiscroll.javascript.min.css" /> <script type="text/javascript" src="../../script/datetime/mobiscroll.javascript.min.js"></script>
<input type="text" placeholder="选择时间" readonly="readonly" v-model="frmData.xjdate" id="startday"/> function datatimeInit() { mobiscroll.datetime('#startday', { lang: 'zh', display: 'bottom', dateFormat: 'yy-mm-dd', timeFormat: 'hh:ii', onBeforeShow: function(event, inst) { api.setFrameAttr({ name: api.frameName, bounces: false }); }, onBeforeClose: function(event, inst) { api.setFrameAttr({ name: api.frameName, bounces: true }); }, onSet: function(event, inst) { if(event.valueText)$api.val($api.byId('startday'), event.valueText); } }); }
2,多级选择器UIActionSelector
/** 多级数据选择器 */ function fnOpenActionSelector(itemsData, callback, num) { api.setFrameAttr({ name: api.frameName, bounces: false }); var colnum = 1; if (num) { colnum = num; } var UIActionSelector = api.require('UIActionSelector'); UIActionSelector.open({ datas: itemsData, layout: { row: 5, col: colnum, height: 30, size: 14, sizeActive: 14, maskBg: 'rgba(0,0,0,0.2)', bg: '#fff', color: '#888', colorActive: '#f00', colorSelected: '#f00' }, animation: true, cancel: { text: '取消', size: 14, w: 90, h: 44, bg: 'transparent', bgActive: 'transparent', color: '#888', colorActive: '#888' }, ok: { text: '确定', size: 14, w: 90, h: 44, bg: 'transparent', bgActive: 'transparent', color: '#03a9f4', colorActive: '#03a9f4' }, title: { text: '', size: 14, h: 44, bg: '#fff', color: '#888' }, fixedOn: api.frameName }, function(ret, err) { api.setFrameAttr({ name: api.frameName, bounces: true }); if (ret) { if (ret.eventType == 'cancel') { UIActionSelector.close(); return; } callback(ret); } else { errormsg(JSON.stringify(err)); } }) }
<div class="aui-list-item-inner aui-list-item-arrow" tapmode onclick="getPrimaryDomain()"> <div class="aui-list-item-label"> 主领域 </div> <div class="aui-list-item-input"> <input type="text" readonly="readonly" v-model="frmData.primarydoman"> <!-- <select v-model="frmData.primarydoman" tapmode onchange="getSubDomain()"> <option v-for="item in primaryDomains" v-bind:value="item.id">{{item.content}}</option> </select> --> </div> </div>
function getPrimaryDomain(){//获取主领域 getCommonDomain(1,function(data){ fnOpenActionSelector(data, function(ret) { if(ret.eventType=="ok") { var info=ret.selectedInfo[0]; VM.frmData.primarydoman= info.name; VM.frmData.primarydomanid= info.value; VM.frmData.subdoman= ''; VM.frmData.zgxwt= ''; } }) }); } function getCommonDomain(param,callback) { console.log("getCommonDomain") fnPost('/api/ProjectHazard/GetHazardList', {parameter:param}, 'application/json;charset=utf-8', true, function(ret, err) { var data; if(ret.ret==0&&ret.data!=null&&ret.data.length>0) { data=new Array(); for (var i = ret.data.length - 1; i >= 0; i--) { data.push({"name":ret.data[i].content,"value":ret.data[i].id}) } } if(callback) { callback(data) } },false,""); }
3,mescroll下拉上拉组件
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="maximum-scale=1.0, minimum-scale=1.0, user-scalable=0, initial-scale=1.0, width=device-width" /> <meta name="format-detection" content="telephone=no, email=no, date=no, address=no"> <title>瓯云APP</title> <link rel="stylesheet" type="text/css" href="../../css/api.css" /> <link rel="stylesheet" type="text/css" href="../../css/aui.css" /> <link rel="stylesheet" type="text/css" href="../../css/style.css" /> <link rel="stylesheet" type="text/css" href="../../script/mescroll/mescroll.min.css" /> <style> .div-top{ background-color: #FCFCFC; } .type-button{ text-align: center; height: 40px; line-height: 40px; } .type-active{ color: #88B459; border-bottom-style:solid; border-bottom-color:#88B459; border-bottom-width: 3px; width: 50%; margin: auto; height: 5px; } .type-fgx{ height:40px; line-height: 40px; float:left; } .type-fgx span{ color: #E3E3E3 } .aui-media-list{ border:1px solid #E4E4E4; border-radius:5px; -moz-border-radius:5px; /* Old Firefox */ margin: 10px; } .img-right{ float: right; display: inline; margin-bottom: auto; margin-top: auto; margin-right: 10px; } .div-status{ color:#FFFFFF; background-color: #87B453; border-radius:5px; -moz-border-radius:5px; /* Old Firefox */ display: inline-block; } </style> </head> <body> <div id="app" v-cloak class="mescroll"> <div class="aui-row div-top"> <div class="aui-col-5"> <div> <ul> <li> <div class="type-button" tapmode onclick="getInspectionList('待办')">待办</div> </li> <li class="type-active" v-if="frmData.type=='待办'"></li> </ul> </div> </div> <div class="aui-col-5"> <div> <ul> <li> <div class="type-fgx"><span>|</span></div> <div class="type-button" tapmode onclick="getInspectionList('处理中')">处理中</div> </li> <li class="type-active" v-if="frmData.type=='处理中'"></li> </ul> </div> </div> <div class="aui-col-5"> <div> <ul> <li> <div class="type-fgx"><span>|</span></div> <div class="type-button" tapmode onclick="getInspectionList('通过')">通过</div> </li> <li class="type-active" v-if="frmData.type=='通过'"></li> </ul> </div> </div> <div class="aui-col-5"> <div> <ul> <li> <div class="type-fgx"><span>|</span></div> <div class="type-button" tapmode onclick="getInspectionList('改进')">改进</div> </li> <li class="type-active" v-if="frmData.type=='改进'"></li> </ul> </div> </div> <div class="aui-col-5"> <div> <ul> <li> <div class="type-fgx"><span>|</span></div> <div class="type-button" tapmode onclick="getInspectionList('整改')">整改</div> </li> <li class="type-active" v-if="frmData.type=='整改'"></li> </ul> </div> </div> </div> <div style="margin: 10px;"></div> <div class="aui-list aui-media-list" v-show="inspectionList.length>0"> <div class="aui-list-item" v-for="item in inspectionList"> <div class="aui-media-list-item-inner"> <div class="aui-list-item-inner"> <div class="aui-list-item-text"> <div class="aui-list-item-title aui-font-size-14">{{item.xj_content}}</div> <div class="aui-list-item-right"><div class="aui-btn aui-btn-success">{{item.type}}</div></div> </div> <div class="aui-list-item-text"> <div class="aui-list-item-title"> <i class="aui-iconfont aui-icon-my" style="margin-right:10px">{{item.cuser}}</i> <i class="aui-iconfont aui-icon-date">{{item.xj_date}}</i> </div> </div> </div> <div class="img-right"> <img src="../../image/ui/index_arrow.png" class="aui-list-img-sm" style="width:0.8rem" /> </div> </div> </div> <!-- <div id="nomore" class="nomore" v-if="inspectionList.length>=total">没有更多数据了</div> <div id="nomore" class="nomore" v-else="inspectionList.length>=total">下翻加载更多信息</div> --> </div> </div> </body> <script type="text/javascript" src="../../script/api.js"></script> <script type="text/javascript" src="../../script/request.js"></script> <script type="text/javascript" src="../../script/vue.js"></script> <script type="text/javascript" src="../../script/mescroll/mescroll.min.js"></script> <script type="text/javascript"> var VM; var mescroll; apiready = function() { VM=new Vue({ el: "#app", data:{ frmData:{ type:'待办' }, inspectionList:[],//巡检列表 total:0, pageindex:1, pagesize:10, mescroll:{} }, mounted:function(){ var vm=this; vm.fnInspectionInit(true); vm.fnInitMescroll(); }, methods:{ fnInitMescroll:function(){ var vm=this; vm.mescroll=new MeScroll("app", { down: { auto: false, callback: vm.fnDownCallback }, up: { auto: false, noMoreSize:1, // isBounce: false, htmlNodata:'<p class="upwarp-nodata">-- 没有更多数据了 --</p>', callback: vm.fnUpCallback } }); }, fnDownCallback:function(){//下拉刷新 var vm=this; setTimeout(function () { vm.fnInspectionInit(false,function(){ vm.mescroll.endSuccess(); //刷新成功后调用此方法隐藏 }) },1000); }, fnUpCallback:function(){//上拉刷新 var vm=this; setTimeout(function () { vm.pageindex++; console.log(vm.pageindex) vm.fnGetCommonInspectionList(false,vm.pageindex,function(data){ if(data!=null&&data.length>0) { for (var i = data.length - 1; i >= 0; i--) { vm.inspectionList.push(data[i]); } } console.log("total:"+vm.total+",length:"+vm.inspectionList.length); if(vm.total>vm.inspectionList.length) { vm.mescroll.optUp.hasNext = true;//可上拉 vm.mescroll.endUpScroll(false);//隐藏上拉 } else { vm.mescroll.optUp.hasNext = false;//可上拉 vm.mescroll.endUpScroll(true);//隐藏上拉 } //vm.mescroll.endSuccess(vm.inspectionList.length,vm.total>vm.inspectionList.length); }); },300); }, fnInspectionInit:function(showProgress,callback){ var vm=this; vm.pageindex=1; vm.fnGetCommonInspectionList(showProgress,vm.pageindex,function(data){ vm.inspectionList=data if(vm.total>vm.inspectionList.length) { vm.mescroll.optUp.hasNext = true;//可上拉 vm.mescroll.endUpScroll(false);//隐藏上拉 } else { vm.mescroll.optUp.hasNext = false;//可上拉 vm.mescroll.endUpScroll(true);//隐藏上拉 } if(callback)callback() }); }, fnGetCommonInspectionList:function(showProgress,pageindex,callback){//获取巡检 var vm=this; var prjid=$api.getStorage('userInfo').myproinfo.id; if(vm.frmData.type=="待办") { var param={parameter:{prj_id:prjid},pageindex:pageindex,pagesize:vm.pagesize}; fnPost('/api/SafeInspection/GetTodoList',param, 'application/json;charset=utf-8', true, function(ret, err) { var data; if(ret!=null&&ret.ret==0&&ret.data.length>0) { data=ret.data; vm.total=ret.total; } else { data=[]; vm.total=0; } if(callback)callback(data); },showProgress,""); } else { var param={parameter:{prj_id:prjid,type:vm.frmData.type},pageindex:pageindex,pagesize:vm.pagesize}; fnPost('/api/SafeInspection/GetOtherList',param, 'application/json;charset=utf-8', true, function(ret, err) { var data; if(ret!=null&&ret.ret==0&&ret.data.length>0) { data=ret.data; vm.total=ret.total; } else { data=[]; vm.total=0; } if(callback)callback(data); },showProgress,""); } } } }); }; function getInspectionList(type){ VM.frmData.type=type; VM.fnInspectionInit(true); } </script> </html>
js下载:https://pan.baidu.com/s/113VxMA48GCtwjlRa2_ZC4g
4,提示组件dialogBox
//提示信息 function alertmsg(msg, funname) { var closeset = true; if (funname == 'exit') { closeset = false; } var dialogBox = api.require('dialogBox'); dialogBox.alert({ texts: { title: '提示信息', content: msg, leftBtnTitle: '确定', }, styles: { bg: '#fff', w: 280, title: { marginT: 10, icon: '', iconSize: 40, titleSize: 16, titleColor: '#000' }, content: { color: '#000', size: 14 }, left: { marginB: 5, marginL: 5, w: 270, h: 40, corner: 2, bg: '#03A9F4', color: '#FFF', size: 14 } }, tapClose: closeset }, function(ret) { if (ret.eventType == 'left') { if (funname) { if (funname == 'exit') { exitThisApp(); } else if (funname == 'back') { goback(); } else { api.execScript({ name: api.winName, frameName: api.frameName, script: funname + '();' }); } } dialogBox.close({ dialogName: 'alert' }); } }); }
//返回 function goback() { api.closeWin(); }
5,图片浏览组件photoBrowser
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="maximum-scale=1.0, minimum-scale=1.0, user-scalable=0, initial-scale=1.0, width=device-width" /> <meta name="format-detection" content="telephone=no, email=no, date=no, address=no"> <title>瓯云APP</title> <link rel="stylesheet" type="text/css" href="../../css/api.css" /> <link rel="stylesheet" type="text/css" href="../../css/style.css" /> <style> </style> </head> <body> </body> <script type="text/javascript" src="../../script/api.js"></script> <script type="text/javascript" src="../../script/request.js"></script> <script type="text/javascript"> var photoBrowser; apiready = function() { api.parseTapmode(); var imgarr = api.pageParam.imgarr; var imgnamearr = api.pageParam.imgnamearr; var name = api.pageParam.name; var imgindex = api.pageParam.imgindex; photoBrowser = api.require('photoBrowser'); var downloadpath = imgarr[imgindex]; photoBrowser.open({ images: imgarr, activeIndex: imgindex, placeholderImg: 'widget://image/banner_bg.png', bgColor: '#000' }, function(ret, err) { if (ret) { if (name) { var f_h = api.frameHeight - 50; api.openFrame({ name: 'imgname_frm', url: 'imgname_frm.html', rect: { x: 0, y: f_h, w: 'auto', h: 50 }, pageParam: { name: name }, bounces: false }); } if (ret.eventType == 'loadImgFail') { api.toast({ msg: '图片下载失败' }); } if (ret.eventType == 'change') { photoBrowser.getIndex(function(ret, err) { if (ret) { var nowindex = ret.index; downloadpath = imgarr[nowindex]; getimgname(nowindex, imgnamearr); } else { alert(JSON.stringify(err)); } }); } if (ret.eventType == 'click') { api.actionSheet({ title: '请选择', cancelTitle: '取消', buttons: ['保存到相册', '关闭窗口'] }, function(ret, err) { if (ret) { if (ret.buttonIndex == 1) { api.download({ url: downloadpath, report: true, cache: true, allowResume: true }, function(ret, err) { if (ret.state == 1) { api.saveMediaToAlbum({ path: ret.savePath }, function(ret, err) { if (ret && ret.status) { api.toast({ msg: '保存成功' }); } else { api.toast({ msg: '保存失败!' }); } }); } else if (ret.state == 2) { alert('保存失败'); } else { //下载中 } }); } else if (ret.buttonIndex == 2) { photoBrowser.close(); goback(); } else { return; } } else { alert(JSON.stringify(err)); } }); } } else { alertmsg('图片打开错误'); } }); }; </script> </html>