HyBrid App 與 Web App 以及 Native App的區別javascript
Web App 開發 (Bootstrap可以開發PC也能夠開發HTML5)css
Web App開發,嚴格來講,並非一個APP軟件,只是一個Web型的微網站.html
優勢: 開發時間短,兼容性強,方便移植。
缺點:必須有網絡的支持,用戶體驗度相對較差。java
Native App 開發node
Native開發,就是一個原生的APP軟件,其主要是經過Java或Object-C來實現原生的手機APP軟件.android
優勢:原生APP,用戶體驗度很是好,能夠調用手機的底層組件。
缺點:開發時間長,兼容性差,必需要掌握Java或Object-C等編程語言ios
HyBrid App 開發ajax
介於WebApp和Native這二者之間的APP,開發時間短,成本低,用戶體驗好,能夠調用手機底層組件,方便移植,是目前以及將來APP開發的流程趨勢。編程
註冊ApiCloud 平臺json
進入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視口
<meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
format-detection
設置:
默認狀況下,手機設備不直接識別手機號碼,郵箱,日期,address地址。
<meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
框架模板
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/> <title>title</title> <link rel="stylesheet" type="text/css" href="api.css"/> <style> body{ } </style> </head> <body> </body> <script type="text/javascript" src="api.js"></script> <script type="text/javascript"> apiready = function(){ }; </script> </html>
入口文件的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<len; i++){ if(doms[i].isEqualNode(el)){ return doms[i]; } } return false; }; var traversal = function(el, selector){ doms = u.domAll(el.parentNode, selector); targetDom = isSame(doms, el); while(!targetDom){ el = el.parentNode; if(el != null && el.nodeType == el.DOCUMENT_NODE){ return false; } traversal(el, selector); } return targetDom; }; return traversal(el, selector); }; u.contains = function(parent,el){ var mark = false; if(el === parent){ mark = true; return mark; }else{ do{ el = el.parentNode; if(el === parent){ mark = true; return mark; } }while(el === document.body || el === document.documentElement); return mark; } }; u.remove = function(el){ if(el && el.parentNode){ el.parentNode.removeChild(el); } }; u.attr = function(el, name, value){ if(!u.isElement(el)){ console.warn('$api.attr Function need el param, el param must be DOM Element'); return; } if(arguments.length == 2){ return el.getAttribute(name); }else if(arguments.length == 3){ el.setAttribute(name, value); return el; } }; u.removeAttr = function(el, name){ if(!u.isElement(el)){ console.warn('$api.removeAttr Function need el param, el param must be DOM Element'); return; } if(arguments.length === 2){ el.removeAttribute(name); } }; u.hasCls = function(el, cls){ if(!u.isElement(el)){ console.warn('$api.hasCls Function need el param, el param must be DOM Element'); return; } if(el.className.indexOf(cls) > -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和引導頁位置:在apiCloud的開發控制檯的端設置
.
自定義loader
自定義loader實現真機同步。
位置:在apiCloud的開發控制檯的模塊-自定義loader
.
使用自定義loader
根據config.xml中的widgt包名<widget id="A0000000000001" version="0.0.1">
建立一個文件夾(文件名爲:A0000000000001
).
當前目錄下G:\SublimeText3\Sublime Text 3x64\Data\Packages\Sublime-APICloud-Loader\appLoader\custom-loader
使用api.openWin
傳遞參數.
當前頁
api.openWin({ name: '', url: '', pageParam: { url: url } });
跳轉頁
api.pageParam.url
接收參數.
apiCloude模塊netAudio
(音樂播放模塊)shareAction
(分享功能)
只要更改模塊的,都須要生成自定義loader
使用模塊
查看netAudio
手冊,使用API.