HyBrid App
HyBrid App 与 Web App 以及 Native App的区别
Web App 开发 (Bootstrap能够开发PC也可以开发HTML5)
Web App开发,严格来说,并不是一个APP软件,只是一个Web型的微网站.
优点: 开发时间短,兼容性强,方便移植。
缺点:必须有网络的支持,用户体验度相对较差。
Native App 开发
Native开发,就是一个原生的APP软件,其主要是通过Java或Object-C来实现原生的手机APP软件.
优点:原生APP,用户体验度非常好,可以调用手机的底层组件。
缺点:开发时间长,兼容性差,必须要掌握Java或Object-C等编程语言
HyBrid App 开发
介于WebApp和Native这两者之间的APP,开发时间短,成本低,用户体验好,可以调用手机底层组件,方便移植,是目前以及未来APP开发的流程趋势。
前期准备
注册ApiCloud 平台
进入ApiCloud开发控制台
创建应用
使用云编译生成App软件
获取App源代码
配置模拟器
下载ApiCloud支持的工具,放入Sublime Text插件包中:
devtools
海马玩模拟器
海马玩模拟器官网
项目结构
ApiCloud
工程目录
css // 样式文件
fature
html // 后缀为.html的框架文件
icon // icon
image // 图片文件
launch
res
script // JavaScript文件
wgt
config.xml // 默认配置文件
index.html // 入口文件
入口文件
App项目必备mate视口
format-detection
设置:
默认情况下,手机设备不直接识别手机号码,邮箱,日期,address地址。
框架模板
title
入口文件的JavaScript
apiready = function(){ // apireday = function() {} // 页面载入 // $api对象 操作DOM, api调用底层方法
$api.fixStatusBar( $api.dom('header') ); // 适配IOS7+,Android4.4+状态栏沉浸式效果。
// 动态计算header的高度,因iOS7+和Andriod4.4+上支持沉浸式效果,因此header的实际高度可能为css样式中声明的44px加上设备状态栏高度,其中iOS状态栏高度为20px,Andriod为25px
var headerH = $api.offset($api.dom('header')).h; // $api.offset().h 获取元素高度
// footer高度为css样式中声明的30px
var footerH = 30;
// frame 的高度为当前window高度减去header和footer的高度
var frameH = api.winHeight - headerH - footerH;
api.setStatusBarStyle({
style: 'dark',
color: '#6ab494'
});
// 打开openFrame框架,参数只有一个,json配置项
api.openFrame({
name: 'win_home', // 框架名称
url: './html/win_home.html', // 打开url连接地址
bounces: true, // 是否可以拖动
rect: { // 设置框架的宽高以及横纵坐标
x: 0,
y: $api.dom('header').offsetHeight,
w: api.winWidth,
h: $api.dom('#main').offsetHeight
}
});
var year = $api.byId('year');
year.innerHTML = new Date().getFullYear();
};
$api // 获取DOM结构
api // 获取底层方法
api.js
apiCloud的JavaScript代码api.js
(function(window){
var u = {};
var isAndroid = (/android/gi).test(navigator.appVersion);
var uzStorage = function(){
var ls = window.localStorage;
if(isAndroid){
ls = os.localStorage();
}
return ls;
};
function parseArguments(url, data, fnSuc, dataType) {
if (typeof(data) == 'function') {
dataType = fnSuc;
fnSuc = data;
data = undefined;
}
if (typeof(fnSuc) != 'function') {
dataType = fnSuc;
fnSuc = undefined;
}
return {
url: url,
data: data,
fnSuc: fnSuc,
dataType: dataType
};
}
u.trim = function(str){
if(String.prototype.trim){
return str == null ? "" : String.prototype.trim.call(str);
}else{
return str.replace(/(^\s*)|(\s*$)/g, "");
}
};
u.trimAll = function(str){
return str.replace(/\s*/g,'');
};
u.isElement = function(obj){
return !!(obj && obj.nodeType == 1);
};
u.isArray = function(obj){
if(Array.isArray){
return Array.isArray(obj);
}else{
return obj instanceof Array;
}
};
u.isEmptyObject = function(obj){
if(JSON.stringify(obj) === '{}'){
return true;
}
return false;
};
u.addEvt = function(el, name, fn, useCapture){
if(!u.isElement(el)){
console.warn('$api.addEvt Function need el param, el param must be DOM Element');
return;
}
useCapture = useCapture || false;
if(el.addEventListener) {
el.addEventListener(name, fn, useCapture);
}
};
u.rmEvt = function(el, name, fn, useCapture){
if(!u.isElement(el)){
console.warn('$api.rmEvt Function need el param, el param must be DOM Element');
return;
}
useCapture = useCapture || false;
if (el.removeEventListener) {
el.removeEventListener(name, fn, useCapture);
}
};
u.one = function(el, name, fn, useCapture){
if(!u.isElement(el)){
console.warn('$api.one Function need el param, el param must be DOM Element');
return;
}
useCapture = useCapture || false;
var that = this;
var cb = function(){
fn && fn();
that.rmEvt(el, name, cb, useCapture);
};
that.addEvt(el, name, cb, useCapture);
};
u.dom = function(el, selector){
if(arguments.length === 1 && typeof arguments[0] == 'string'){
if(document.querySelector){
return document.querySelector(arguments[0]);
}
}else if(arguments.length === 2){
if(el.querySelector){
return el.querySelector(selector);
}
}
};
u.domAll = function(el, selector){
if(arguments.length === 1 && typeof arguments[0] == 'string'){
if(document.querySelectorAll){
return document.querySelectorAll(arguments[0]);
}
}else if(arguments.length === 2){
if(el.querySelectorAll){
return el.querySelectorAll(selector);
}
}
};
u.byId = function(id){
return document.getElementById(id);
};
u.first = function(el, selector){
if(arguments.length === 1){
if(!u.isElement(el)){
console.warn('$api.first Function need el param, el param must be DOM Element');
return;
}
return el.children[0];
}
if(arguments.length === 2){
return this.dom(el, selector+':first-child');
}
};
u.last = function(el, selector){
if(arguments.length === 1){
if(!u.isElement(el)){
console.warn('$api.last Function need el param, el param must be DOM Element');
return;
}
var children = el.children;
return children[children.length - 1];
}
if(arguments.length === 2){
return this.dom(el, selector+':last-child');
}
};
u.eq = function(el, index){
return this.dom(el, ':nth-child('+ index +')');
};
u.not = function(el, selector){
return this.domAll(el, ':not('+ selector +')');
};
u.prev = function(el){
if(!u.isElement(el)){
console.warn('$api.prev Function need el param, el param must be DOM Element');
return;
}
var node = el.previousSibling;
if(node.nodeType && node.nodeType === 3){
node = node.previousSibling;
return node;
}
};
u.next = function(el){
if(!u.isElement(el)){
console.warn('$api.next Function need el param, el param must be DOM Element');
return;
}
var node = el.nextSibling;
if(node.nodeType && node.nodeType === 3){
node = node.nextSibling;
return node;
}
};
u.closest = function(el, selector){
if(!u.isElement(el)){
console.warn('$api.closest Function need el param, el param must be DOM Element');
return;
}
var doms, targetDom;
var isSame = function(doms, el){
var i = 0, len = doms.length;
for(i; i -1){
return true;
}else{
return false;
}
};
u.addCls = function(el, cls){
if(!u.isElement(el)){
console.warn('$api.addCls Function need el param, el param must be DOM Element');
return;
}
if('classList' in el){
el.classList.add(cls);
}else{
var preCls = el.className;
var newCls = preCls +' '+ cls;
el.className = newCls;
}
return el;
};
u.removeCls = function(el, cls){
if(!u.isElement(el)){
console.warn('$api.removeCls Function need el param, el param must be DOM Element');
return;
}
if('classList' in el){
el.classList.remove(cls);
}else{
var preCls = el.className;
var newCls = preCls.replace(cls, '');
el.className = newCls;
}
return el;
};
u.toggleCls = function(el, cls){
if(!u.isElement(el)){
console.warn('$api.toggleCls Function need el param, el param must be DOM Element');
return;
}
if('classList' in el){
el.classList.toggle(cls);
}else{
if(u.hasCls(el, cls)){
u.removeCls(el, cls);
}else{
u.addCls(el, cls);
}
}
return el;
};
u.val = function(el, val){
if(!u.isElement(el)){
console.warn('$api.val Function need el param, el param must be DOM Element');
return;
}
if(arguments.length === 1){
switch(el.tagName){
case 'SELECT':
var value = el.options[el.selectedIndex].value;
return value;
break;
case 'INPUT':
return el.value;
break;
case 'TEXTAREA':
return el.value;
break;
}
}
if(arguments.length === 2){
switch(el.tagName){
case 'SELECT':
el.options[el.selectedIndex].value = val;
return el;
break;
case 'INPUT':
el.value = val;
return el;
break;
case 'TEXTAREA':
el.value = val;
return el;
break;
}
}
};
u.prepend = function(el, html){
if(!u.isElement(el)){
console.warn('$api.prepend Function need el param, el param must be DOM Element');
return;
}
el.insertAdjacentHTML('afterbegin', html);
return el;
};
u.append = function(el, html){
if(!u.isElement(el)){
console.warn('$api.append Function need el param, el param must be DOM Element');
return;
}
el.insertAdjacentHTML('beforeend', html);
return el;
};
u.before = function(el, html){
if(!u.isElement(el)){
console.warn('$api.before Function need el param, el param must be DOM Element');
return;
}
el.insertAdjacentHTML('beforebegin', html);
return el;
};
u.after = function(el, html){
if(!u.isElement(el)){
console.warn('$api.after Function need el param, el param must be DOM Element');
return;
}
el.insertAdjacentHTML('afterend', html);
return el;
};
u.html = function(el, html){
if(!u.isElement(el)){
console.warn('$api.html Function need el param, el param must be DOM Element');
return;
}
if(arguments.length === 1){
return el.innerHTML;
}else if(arguments.length === 2){
el.innerHTML = html;
return el;
}
};
u.text = function(el, txt){
if(!u.isElement(el)){
console.warn('$api.text Function need el param, el param must be DOM Element');
return;
}
if(arguments.length === 1){
return el.textContent;
}else if(arguments.length === 2){
el.textContent = txt;
return el;
}
};
u.offset = function(el){
if(!u.isElement(el)){
console.warn('$api.offset Function need el param, el param must be DOM Element');
return;
}
var sl = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
var st = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
var rect = el.getBoundingClientRect();
return {
l: rect.left + sl,
t: rect.top + st,
w: el.offsetWidth,
h: el.offsetHeight
};
};
u.css = function(el, css){
if(!u.isElement(el)){
console.warn('$api.css Function need el param, el param must be DOM Element');
return;
}
if(typeof css == 'string' && css.indexOf(':') > 0){
el.style && (el.style.cssText += ';' + css);
}
};
u.cssVal = function(el, prop){
if(!u.isElement(el)){
console.warn('$api.cssVal Function need el param, el param must be DOM Element');
return;
}
if(arguments.length === 2){
var computedStyle = window.getComputedStyle(el, null);
return computedStyle.getPropertyValue(prop);
}
};
u.jsonToStr = function(json){
if(typeof json === 'object'){
return JSON && JSON.stringify(json);
}
};
u.strToJson = function(str){
if(typeof str === 'string'){
return JSON && JSON.parse(str);
}
};
u.setStorage = function(key, value){
if(arguments.length === 2){
var v = value;
if(typeof v == 'object'){
v = JSON.stringify(v);
v = 'obj-'+ v;
}else{
v = 'str-'+ v;
}
var ls = uzStorage();
if(ls){
ls.setItem(key, v);
}
}
};
u.getStorage = function(key){
var ls = uzStorage();
if(ls){
var v = ls.getItem(key);
if(!v){return;}
if(v.indexOf('obj-') === 0){
v = v.slice(4);
return JSON.parse(v);
}else if(v.indexOf('str-') === 0){
return v.slice(4);
}
}
};
u.rmStorage = function(key){
var ls = uzStorage();
if(ls && key){
ls.removeItem(key);
}
};
u.clearStorage = function(){
var ls = uzStorage();
if(ls){
ls.clear();
}
};
/*by king*/
u.fixIos7Bar = function(el){
if(!u.isElement(el)){
console.warn('$api.fixIos7Bar Function need el param, el param must be DOM Element');
return;
}
var strDM = api.systemType;
if (strDM == 'ios') {
var strSV = api.systemVersion;
var numSV = parseInt(strSV,10);
var fullScreen = api.fullScreen;
var iOS7StatusBarAppearance = api.iOS7StatusBarAppearance;
if (numSV >= 7 && !fullScreen && iOS7StatusBarAppearance) {
el.style.paddingTop = '20px';
}
}
};
u.fixStatusBar = function(el){
if(!u.isElement(el)){
console.warn('$api.fixStatusBar Function need el param, el param must be DOM Element');
return;
}
var sysType = api.systemType;
if(sysType == 'ios'){
u.fixIos7Bar(el);
}else if(sysType == 'android'){
var ver = api.systemVersion;
ver = parseFloat(ver);
if(ver >= 4.4){
el.style.paddingTop = '25px';
}
}
};
u.toast = function(title, text, time){
var opts = {};
var show = function(opts, time){
api.showProgress(opts);
setTimeout(function(){
api.hideProgress();
},time);
};
if(arguments.length === 1){
var time = time || 500;
if(typeof title === 'number'){
time = title;
}else{
opts.title = title+'';
}
show(opts, time);
}else if(arguments.length === 2){
var time = time || 500;
var text = text;
if(typeof text === "number"){
var tmp = text;
time = tmp;
text = null;
}
if(title){
opts.title = title;
}
if(text){
opts.text = text;
}
show(opts, time);
}
if(title){
opts.title = title;
}
if(text){
opts.text = text;
}
time = time || 500;
show(opts, time);
};
u.post = function(/*url,data,fnSuc,dataType*/){
var argsToJson = parseArguments.apply(null, arguments);
var json = {};
var fnSuc = argsToJson.fnSuc;
argsToJson.url && (json.url = argsToJson.url);
argsToJson.data && (json.data = argsToJson.data);
if(argsToJson.dataType){
var type = argsToJson.dataType.toLowerCase();
if (type == 'text'||type == 'json') {
json.dataType = type;
}
}else{
json.dataType = 'json';
}
json.method = 'post';
api.ajax(json,
function(ret,err){
if (ret) {
fnSuc && fnSuc(ret);
}
}
);
};
u.get = function(/*url,fnSuc,dataType*/){
var argsToJson = parseArguments.apply(null, arguments);
var json = {};
var fnSuc = argsToJson.fnSuc;
argsToJson.url && (json.url = argsToJson.url);
//argsToJson.data && (json.data = argsToJson.data);
if(argsToJson.dataType){
var type = argsToJson.dataType.toLowerCase();
if (type == 'text'||type == 'json') {
json.dataType = type;
}
}else{
json.dataType = 'text';
}
json.method = 'get';
api.ajax(json,
function(ret,err){
if (ret) {
fnSuc && fnSuc(ret);
}
}
);
};
/*end*/
window.$api = u;
})(window);
系统基本信息
// 获取引擎版本号
var ver = api.version;
// 获取系统类型(Android或iOS)
var sType = api.systemType;
// 获取系统的版本信息
var sVer = api.systemVersion;
// 获取设备标识
var id = api.deviceId;
// 获取设备的型号
var model = api.deviceModel;
// 获取设备的名称(HTC | 小米| 魅族| 华为)
var name = api.deviceName;
// 获取网络连接类型 (wifi|3G|4G)
var cType = api.connectionType;
// 获取window窗体的名称
var winName = api.winName;
// 获取window窗体的高度
var winHeight = api.winHeight;
// 获取frame框架的名称
var frameName = api.frameName || '';
// 获取frame框架的宽度
var frameWidth = api.frameWidth || '';
// 获取frame框架的高度
var frameHeight = api.frameHeight || '';
logo和引导页
logo和引导页位置:在apiCloud的开发控制台的端设置
.
自定义loader
自定义loader实现真机同步。
位置:在apiCloud的开发控制台的模块-自定义loader
.
使用自定义loader
根据config.xml中的widgt包名
创建一个文件夹(文件名为:A0000000000001
).
当前目录下G:\SublimeText3\Sublime Text 3x64\Data\Packages\Sublime-APICloud-Loader\appLoader\custom-loader
apiCloud使用模块
使用api.openWin
传递参数.
当前页
api.openWin({
name: '',
url: '',
pageParam: {
url: url
}
});
跳转页
api.pageParam.url
接收参数.
apiCloude模块netAudio
(音乐播放模块)shareAction
(分享功能)
只要更改模块的,都需要生成自定义loader
使用模块
查看netAudio
手册,使用API.