HTML5 APP开发常用事项
1.常用标签
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="apple-touch-fullscreen" content="yes" />
apple-mobile-web-app-capable,这meta的作用就是删除默认的苹果工具栏和菜单栏.
apple-mobile-web-app-status-bar-style的作用是控制状态栏显示样式。
apple-touch-fullscreen添加到主屏幕“后,全屏显示
<meta property="og:title" content="xxx">
<meta property="og:type" content="xxx">
<meta property="og:url" content="xxx">
<meta property="og:image" content="xxx">
<meta property="og:site_name" content="xxx">
<meta property="og:description" content="xxx">
og是一种新的HTTP头部标记,即Open Graph Protocol,这种协议可以让网页成为一个“富媒体对象”,一般是用于方便分享到facebook,renren用的.
1 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> 2 <!-- 关于X-UA-Compatible --> 3 <meta http-equiv="X-UA-Compatible" content="IE=6" ><!-- 使用IE6 --> 4 <meta http-equiv="X-UA-Compatible" content="IE=7" ><!-- 使用IE7 --> 5 <meta http-equiv="X-UA-Compatible" content="IE=8" ><!-- 使用IE8 -->
浏览器内核控制:
<meta name="renderer" content="webkit|ie-comp|ie-stand">
更多meta内容可以参考:http://segmentfault.com/a/1190000002407912
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="img/apple-touch-icon-57.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="img/apple-touch-icon-72.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="img/apple-touch-icon-114.png">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="img/apple-touch-icon-144.png">
<link rel="icon" href="img/favicon.ico" />
针对不同苹果设备,使用不同的图标。
2.ajax加载技术
在ipad设备中,ajax加载时候或许会出现些小毛病,可能与数据库操作产生冲突之类的,极端的bug.参考下面的脚本来解决问题。
1 function ajax(url,options) {
2 var xhr;
3 var success = options.success, error = options.error;
4 if(typeof XMLHttpRequest !== 'undefined') {
5 xhr = new XMLHttpRequest();
6 } else {
7 var versions = ["MSXML2.XmlHttp.5.0",
8 "MSXML2.XmlHttp.4.0",
9 "MSXML2.XmlHttp.3.0",
10 "MSXML2.XmlHttp.2.0",
11 "Microsoft.XmlHttp"]
12
13 for(var i = 0, len = versions.length; i < len; i++) {
14 try {
15 xhr = new ActiveXObject(versions[i]);
16 break;
17 }
18 catch(e){}
19 }
20 }
21
22 xhr.onreadystatechange = function() {
23 if(xhr.readyState < 4) {
24 return;
25 }
26 if(xhr.status !== 200) {
27 return;
28 }
29 if(xhr.readyState === 4) {
30 var responseText = xhr.responseText;
31 if(responseText && responseText!=''){
32 success(JSON.parse(responseText));
33 } else {
34 success(xhr);
35 }
36 }
37 }
38
39 xhr.open('GET', url, true);
40 xhr.send('');
41 }
3.离线
< html manifest="test.manifest">
manifest文件结构:
1 CACHE MANIFEST 2 3 # VERSION 0.3 4 5 # 缓存文件 6 CACHE: 7 index.html 8 images/a.png 9 js/b.js 10 css/c.css 11 12 # 不需要缓存的文件 13 NETWORK: 14 /online/ 15 16 # 可替代的方案 17 FALLBACK: 18 a.css b.css
在html标签中写入manifest的方式,会将默认将html当前页面缓存,有一个方式可以避免,就是页面中写一个空的iframe,在iframe的html中添加manifest.
4.设备检测
1 if ('standalone' in navigator && navigator.standalone) {
2 //todo
3 } else {
4 //todo
5 }
6 var targetDPI, viewport, ua, version, classGroup;
7 ua = navigator.userAgent.toLowerCase();
8 window.deprecatedDeviceIsAndroid = (ua.search('android') > -1);
9 window.deprecatedDeviceIsiPad = (ua.search('ipad') > -1);
10
11 viewport = 'initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no';
12 if (window.deprecatedDeviceIsAndroid) {
13 classGroup = 'android';
14 targetDPI = 160;
15 if (ua.match(/gt-p10\d0|sgh-i987|sph-p100|sgh-t849|sch-i800|shw-m180s|sc-01c/)) targetDPI = 'device-dpi';
16 viewport += ', target-densityDpi='+targetDPI+', width=device-width';
17 if(window.mainActivity){
18 return;
19 } else if(ua.indexOf("chrome")>0){
20 return;
21 } else {
22 window.location = 'index_android.html';
23 }
24 } else if (window.deprecatedDeviceIsiPad) {
25 classGroup = 'iPad';
26 if (ua.match(/iPad;.*CPU.*OS 7_\d/i)) classGroup += ' iOS7'; window.osVersion = 'iOS7';
27 if (ua.match(/iPad;.*CPU.*OS 8_\d/i)) classGroup += ' iOS8'; window.osVersion = 'iOS8';
28 if (window.navigator.standalone) classGroup += ' standalone';
29
30 version = ua.match(/cpu (?:\w+ )?os (\d+)_?(\d+)?/);
31 if (version && (version[1] < 6 )) {
32 window.location = 'http://www.xxx.com';
33 }
34
35 } else {
36 window.location = 'index_desktop.html';
37 }
38 document.write('<meta name="viewport" content="' + viewport + '" />');
39 document.getElementsByTagName('html')[0].className = classGroup;
5.路由
1 var Router = APP.Router = function(){
2 function Router(){
3 }
4 Router.prototype.setup = function(routemap, defaultFunc){
5 var that = this, rule, func;
6 this.routemap = [];
7 this.defaultFunc = defaultFunc;
8 for (var rule in routemap) {
9 if (!routemap.hasOwnProperty(rule)) continue;
10 that.routemap.push({
11 rule: new RegExp(rule, 'i'),
12 func: routemap[rule]
13 });
14 }
15 window.onhashchange = function() {
16 that.start();
17 }
18 };
19 Router.prototype.start = function(){
20 var hash = location.hash, route, matchResult;
21 for (var routeIndex in this.routemap){
22 route = this.routemap[routeIndex];
23 matchResult = hash.match(route.rule);
24 if (matchResult){
25 route.func.apply(window, matchResult.slice(1));
26 break;
27 }
28 }
29 this.defaultFunc();
30 };
31 return Router;
32 }();
6.构建工具
npm install chokidar //用于监测文件变化
npm install node-smushit //用于图片优化
npm install open //用于打开程序
npm isntall uglify-js //用于压缩脚本
文件的md5加密:
1 var crypto = require('crypto');
2 var fs = require('fs');
3
4 var rs = fs.createReadStream('./file.tgz');
5
6 var hash = crypto.createHash('md5');
7 rs.on('data', hash.update.bind(hash));
8
9 rs.on('end', function () {
10 console.log(hash.digest('hex'));
11 });
编译LESS:(来自http://blog.csdn.net/xuyanquan/article/details/41118123)
1 var fs = require('fs'),
2 path = require('path'),
3 exec = require('child_process').exec,
4 sourcePath, targetPath;
5
6 //获取命令行中的路径
7 process.argv.forEach(function (val, index, array) {
8 if (index == 2) {
9 sourcePath = val;
10 }
11 if (index == 3) {
12 targetPath = val;
13 }
14 })
15
16 var lessc = function (rootPath, targetPath) {
17 //取得当前绝对路径
18 rootPath = path.resolve(rootPath);
19 //目标路径绝对路径
20 targetPath = path.resolve(targetPath);
21 //判断目录是否存在
22 fs.exists(rootPath, function (exists) {
23 //路径存在
24 if (exists) {
25 //获取当前路径下的所有文件和路径名
26 var childArray = fs.readdirSync(rootPath);
27 if (childArray.length) {
28 for (var i = 0; i < childArray.length; i++) {
29 var currentFilePath = path.resolve(rootPath, childArray[i]);
30 var currentTargetPath = path.resolve(targetPath, childArray[i])
31 //读取文件信息
32 var stats = fs.statSync(currentFilePath);
33 //若是目录则递归调用
34 if (stats.isDirectory()) {
35 lessc(currentFilePath, currentTargetPath);
36 } else {
37 //判断文件是否为less文件
38 if (path.extname(currentFilePath) === ".less") {
39 var newFilePath = path.resolve(targetPath, path.basename(currentFilePath, '.less') + ".css");
40 if (!fs.existsSync(targetPath)) {
41 fs.mkdirSync(targetPath);
42 }
43 console.log(newFilePath);
44 exec("lessc -x " + currentFilePath + " > " + newFilePath);
45 }
46 }
47 }
48 }
49 } else {
50 console.log("directory is not exists");
51 }
52 });
53 }
54
55 lessc('./', './css/');
node创建命令行工具(来自http://www.cnblogs.com/frontendBY/p/5268394.html):
1 mkdir mingling
2 cd mingling
3 npm init //创建package.json
4 mkdir bin
5 cd.>index.js //创建bin/index.js文件
6
7 //index.js文件内容
8 #!/usr/bin/env node
9 var fs = require('fs'),
10 path = process.cwd();
11
12 var run = function(obj) {
13 if (obj[0] === '-v') {
14 console.log('version is 1.0.0');
15 } else if (obj[0] === '-h') {
16 console.log('usage:');
17 console.log(' -v --version [show version]');
18 } else {
19 fs.readdir(path, function(err, files) {
20 if (err) {
21 return console.log(err);
22 }
23 for (var i = 0; i < files.length; i += 1) {
24 console.log(files[i]);
25 }
26 });
27 }
28 };
29 run(process.argv.slice(2));
30
31 //第一行#!开头字符黄表示用后面的路径所示的程序来执行当前文件。
32
33 package.json文件内容如下所示:
34 {
35 "name": "mingling",
36 "version": "1.0.0",
37 "description": "",
38 "main": "index.js",
39 "bin": {"list": "bin/index.js"},
40 "scripts": {
41 "test": "echo \"Error: no test specified\" && exit 1"
42 },
43 "author": "ken",
44 "license": "ISC"
45 }
46
47 //需要注意的只有bin的配置,bin里的配置将bin/index.js映射到list命令中。
上面的代码运行没有问题之后,就可以将当前目录模块安装到全局了,有两种方式安装:
1.install
npm install . -g
2.link
npm link //npm link 只是做了一个软链而已。它指向你包的目录
安装成功后就可以在终端环境下执行命令了:
~ list
~ list -v
~ list -h
发布模块到线上:
1.npm adduser
2.npm login
3.npm publish
除了以上这些还有css 压缩,coffeescript编译,脚本合并等工具,通过node的整合,可以形成一套完整的前端构建方案。