移动h5开发逐渐成为一种主流,也不断趋向于成熟。硬件和浏览器的不断更新,曾经的浏览器兼容也不再是开发者的噩梦。
接触h5开发一年多,从最初的新手到现在,陆陆续续遇到过很多坑。这里把想到的一些经验与资源罗列出来,给刚入h5的同学带来一些帮助。
基础知识
新手建议看看下面的在线教程。
html,css,JavaScript,jQuery在线教程: w3school在线教程:http://www.w3school.com.cn/ 菜鸟教程:http://www.runoob.com/
参考手册: jQuery:http://hemin.cn/jq/ css:http://css.doyoe.com/
h5页面基本组成
<head >
<meta charset ="utf-8" >
<title > titletitle >
head >
<body >
body >
meta viewport模板
<html >
<head >
<meta charset ="utf-8" >
<meta content ="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name ="viewport" >
<meta content ="yes" name ="apple-mobile-web-app-capable" >
<meta content ="black" name ="apple-mobile-web-app-status-bar-style" >
<meta content ="telephone=no" name ="format-detection" >
<meta content ="email=no" name ="format-detection" >
<title > 标题title >
<link rel ="stylesheet" href ="index.css" >
head >
<body >
这里开始内容
body >
html >
以上支持响应式布局设计。
有用的js类库
jQuery
这个必须学会的。 在线教程:http://www.w3school.com.cn/jquery/index.asp 在线手册:http://hemin.cn/jq/
Zepto
Zepto和jQuery基本是一样的,只是由于其体积更小,适合移动端使用。 如果你会用jquery,那么你也会用zepto。注意,zepto并没有实现jQuery的所有功能,这也就意味着jQuery的插件Zepto不能直接拿来用。
最新版是1.1.6。
API参考:http://www.css88.com/doc/zeptojs_api/ github: https://github.com/madrobby/zepto
注意: Zepto默认构建包含以下模块: Core, Ajax, Event, Form, IE.
也就是意味着下列模块可能需要自己加入或重新编译进去:detect
、fx、fx_methods、assets、data、deferred、callbacks、selector 、touch
、gesture、stack、ios3。
underscore
为JavaScript提供了很多好用的方法,可以当工具函数库使用。
Underscore提供了100多个函数,包括常用的: map, filter, invoke — 当然还有更多专业的辅助函数,如:函数绑定, JavaScript模板功能,创建快速索引, 强类型相等测试, 等等.
API参考:http://www.css88.com/doc/underscore/
backbone
前端的MVC框架。Backbone.js为复杂WEB应用程序提供模型(models)、集合(collections)、视图(views)的结构。
初学者了解即可。
API参考:http://www.css88.com/doc/backbone/
KISSY
官网说是一款强大的JavaScript框架。实质就是类jQuery+UI组件
,淘宝网自己用的。感兴趣的可以了解了解。 http://docs.kissyui.com/
前端UI框架
想要快速构建一个网站或应用,尤其在初入移动端开发,对移动端布局、响应式不熟悉的时候,使用已有的UI框架可以节省很多时间。网上有很多开源的UI框架。
如何选择呢? 1、组件小(CSS+JS 总大小最好200KB以内) 2、提供常用组件:如表单、按钮、对话框、toast等。最好还有日历、时间选择、TAB标签、Popup、操作表、路由可供使用。 3、支持响应式。必须的。
下面推荐几款供使用。曾经都使用过。
移动端: FrozenUI:http://frozenui.github.io/ SUI Mobile:http://m.sui.taobao.org/ weui:https://github.com/weui/weui
缺陷与优点:FrozenUI缺少日历、时间选择、操作表、路由等组件,但体积很小,使用简单。SUI路由不好用,体积偏大。这两款均依赖Zepto。weui目前仅提供CSS组件,没有集成JS。
Web端: Bootstrap:http://www.bootcss.com/ ZUI:http://zui.sexy/#/
缺陷与优点:Bootstrap算是很有名的了。WEB建站必备,是很多人接触的第一个UI框架,建议学会。直接使用Bootstrap3版本即可。后台管理可以使用ZUI。
js插件
弹出层
artDialog 4.1.7 http://lab.seaning.com/
layer(jQuery弹出层插件) http://layer.layui.com/
layer.mobile http://layer.layui.com/mobile/
SweetAlert:漂亮的alert美化插件 http://www.wufangbo.com/sweet-alert/
表单验证
jquery.validate:http://www.cnblogs.com/52fhy/p/4953556.html
幻灯片
jquery.SuperSlide http://www.superslide2.com/demo.html
Swiper2 http://2.swiper.com.cn/
编辑器
kindeditor http://kindeditor.net/demo.php
UEditor http://ueditor.baidu.com/website/index.html
联想输入(自动补全)
autocomplete:http://www.cnblogs.com/52fhy/p/4456092.html bigautocomplete:http://www.cnblogs.com/52fhy/p/4455988.html
日期选择
jquery-datepicker http://www.helloweba.com/view-blog-168.html
My97DatePicker http://www.my97.net/
pickadate.js响应式时间选择器(依赖jQuery) https://github.com/amsul/pickadate.js
layDate - js日期控件与时间插件官方讲解 http://laydate.layui.com/
图片画廊&放大
baguetteBox.js响应式画廊插件(纯JS) http://www.cnblogs.com/52fhy/p/4836463.html
图片懒加载
lazyload.js: http://www.cnblogs.com/52fhy/p/5344182.html jquery.lazyload.js: http://www.appelsiini.net/projects/lazyload
图标字体(iconfont)
在做移动端项目中,经常会用到很多小图标,如首页、分享、回复、赞、返回等,这些Icon(图标)一般都是纯色的。
我们一般有三种方式来展示这些图标: 1、每个图标对应一张图片,通过设置图片的大小完成; 2、将所有图标放在一张图片上,通过background-position
属性进行偏移; 3、图标字体解决方案:将图标做成字体。
优缺点非分析: 1、方案1每个图标都会被加载一次,增大服务器压力;图片放大会模糊; 2、方案2图片仅会加载一次,但难点是设置好位移;不方便新增图标;图片放大会模糊; 3、方案3是这两年新起的方案,不考虑旧浏览器的情况下,可以解决上述所有缺点:图标矢量化,不会模糊;在一个字体文件内,不会多次请求;可以方便的添加新的图标。
想深入了解的同学可以看下面资源:
图标字体化浅谈 http://www.cnblogs.com/52fhy/p/5296545.html
图标字体资源汇总
iconfont可在线编辑,可导入导出 https://icomoon.io/app/#/select
阿里icon font字库:图标很多 http://www.iconfont.cn/
阿里妈妈M2UX的一个icon font字体图标字库 http://fontello.com/
Font Awesome, 为 Bootstrap 而创造的图标字体 http://www.bootcss.com/p/font-awesome/
自动化集成
grunt
使用grunt合并压缩js、css文件 : http://www.cnblogs.com/52fhy/p/4954107.html
gulp
gulp.js - 基于流的自动化构建工具 http://www.gulpjs.com.cn/
一点 | gulp详细入门教程 http://www.ydcss.com/archives/18
其它
手机拍照和上传图片
的accept 属性
<input type ="file" capture ="camera" accept ="image/*" name ="image" id ="file" >
<input type ="file" accept ="video/*" >
使用总结: 加了capture
属性后h5有拍照功能
ios 有拍照、录像、选取本地图片功能 部分android只有选取本地图片功能 winphone不支持 input控件默认外观丑陋
去除浏览器按钮默认样式
发现在安卓和电脑上正常的按钮到苹果手机上不正常了,后来发现是浏览器有默认样式。禁止就行了。
input {
-webkit-appearance : none;
}
隐藏滚动条
可以不显示滚动条但页面依旧可以滚动。仅webkit内核浏览器中有效(Chrome,Safari)。嫌滚动条不好看的同学可以试试。
::-webkit-scrollbar {
width : 0px
}
字体单位font-size选择px还是rem
px
: 这个是绝对大小,我们一般使用px来设置我们的文本,因为他比较稳定和精确。
em
: 相对大小,相对于父元素的值,计算公式:需要转换的像素值 / 父元素的font-size = em值
rem
: 相对大小,W3C官网描述是font size of the root element
,即rem是相对于根元素。
对于只需要适配少部分手机设备,且分辨率对页面影响不大的,使用px即可。 对于需要适配各种移动设备,使用rem,例如只需要适配iPhone和iPad等分辨率差别比较挺大的设备。
详细请阅读: CSS3中REM使用详解 http://www.w3cways.com/1713.html
jQuery on()方法代替live()方法动态绑定事件
从 jQuery 1.7 开始,不再建议使用 .live()
方法。请使用 .on()
代替 来添加事件处理。使用旧版本的用户,应该优先使用 .delegate()
来替代 .live()
。
手册里说建议使用 .on()
代替.live()
方法,但是没有给出例子。
之前项目中用.on()
来测试结果发现,居然动态生成的标签点击了没反应,而.live()
方法却能够支持。后来才发现,jQuery 使用.on()
绑定动态生成的元素时,不能直接用该对象操作,而是选择其非动态生成的父节点然后再找到本身才能达到效果。例如:
$("p" ).live("click" , function ( ) {
$(this ).after("Another paragraph!
" );
});
这里的p
标签是动态生成的,直接使用.on()
是没办法触发.click
事件的。但这样是可以的:
$(document ).on("click" ,'p' , function ( ) {
$(this ).after("Another paragraph!
" );
});
选择父节点document
再找到动态生成的p
标签。
动态引入js文件
var oHead = document .getElementsByTagName('head' )[0 ];
var oScript= document .createElement("script" );
oScript.type = "text/javascript" ;
oScript.src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js" ;
oHead.appendChild(oScript);
动态创建meta属性
var meta = document .createElement('meta' );
meta.setAttribute('name' , 'viewport' );
meta.setAttribute('content' , 'initialwidth=device-width,initial-scale=1' );
document .getElementsByTagName('head' )[0 ].appendChild(meta);
CSS设置文字省略隐藏
.ellipsis_txt {
display : -webkit-box;
-webkit-line-clamp : 2 ;
overflow : hidden;
word-break : break-all;
text-overflow : ellipsis;
-webkit-box-orient : vertical;
}
-webkit-line-clamp: 2;
表示最多显示2行文字。
另外一种,默认显示一行:
.ellipsis {
overflow : hidden;
text-overflow : ellipsis;
display : inline-block;
width : 95% ;
}
必须是块级元素,必须指定宽度。
元素float后,父元素没有高度问题
在CSS里定义了如CLASS类这样的浮动后,你会发现父div名box没有高度,所以又时候你可能感觉到父div的margin没有效果,这种情况下,你只需要给父div加个overflow:hidden
就可以了,譬如
.box {overflow :hidden}
更多阅读:[译] 关于CSS中的float和position (父容器div内的子元素div为float时,父元素无法撑开(或高度自适应)的解决方式)
fixed定位与虚拟键盘冲突问题
移动端里 输入框input获取焦点得时,虚拟键盘会把fixed元素顶上去。
使用媒体查询解决:
@media (max-height: 400px ) {
.footer {
display : none;
}
}
div之间的空隙?
当两个div紧挨着的时候没有空隙,中间有空格或换行就有了空隙,这是为什么?
使用 display: inline-block 会导致元素之间有空隙 解决方法: 父元素设置 font-size: 0;
微信不支持支付宝方法
使用iframe。在alipay_submit.class.php
文件中增加一个方法:
function buildRequestUrl ($para_temp, $method, $button_name) {
$para = $this->buildRequestParaToString($para_temp);
$url = $this->alipay_gateway_new. $para;
$sHtml = '
' ;
$sHtml .= '' ;
return $sHtml;
}
注意这里的$this->alipay_gateway_new
是http://wappaygw.alipay.com/service/rest.htm
。
然后调用时将默认的buildRequestForm
改为buildRequestUrl
方法即可。 但是有个问题,我们设置的callback页面(一般是订单详情,显示支付成功与否的页面),这时候也在iframe里面,我们需要跳出。方法是: 在callback页面增加一段js代码;
if (top.location!=self .location)top.location=self .location;
就可以了。
1,工具WebStorm
让网页的宽度自适应屏幕
1)html上加入
发确保网页的效果
2)
加上以下语句可使网页在苹果设备上运行更好
3)加入这句话可以定义iphone的添加到主屏幕的图标
网页打开方式:链接
target的值:_self(相同窗口,浏览器默认)、_top(整页窗口)和_parent(父窗口)相同、_blank(在新建的窗口打开)
表示页面中的所有链接都在新窗口打开
madinc.co //
autocomplete="off"//去掉输入框的历史记录
querySelector只返回匹配的第一个元素,如果没有匹配项,返回null。
querySelectorAll返回匹配的元素集合,如果没有匹配项,返回空的nodelist(节点数组)。
document.querySelector('#indicator > li.active').className = '';//......
innerheight: 返回窗口的文档显示区的高度。 (IE用document.documentElement.clientHeight)
innerwidth 返回窗口的文档显示区的宽度。(IE用document.documentElement.clientWidth )
<-----------------------------------------------------------------HTML5---------------->
HTML5新增:
contenteditable:设置是否允许用户编辑元素
contentextmenu:给元素设置一个上下文菜单
draggable:设置是否允许用户拖动元素
irrelevant:设置元素是否相关。不显示非相关的元素。
ref:引用另一个文档或本文档上另一个位置。仅在template属性设置时使用
registrationmark:为元素设置拍照。可规定于任何元素的后代,除了元素
// 控制手机全屏 : 强制让文档的宽度与设备的宽度保持1:1, 并且文档最大的宽度比例 是1.0,且不允许用户点击屏幕放大浏览
//viewport:可视区域
//initial-scale:初始的缩放比例;user-scalable:用户是否可以手动缩放;
//minimum-scale:允许用户缩放的最小比例;maximum-scale :允许用户缩放的最大比例
//在手机中不会将网页中的一串数字(电话号码)显示为拨号的超链接,默认telephone=yes
//删除黙认的苹果菜单栏和工具栏,如需要苹果菜单栏和工具栏可不加
//控制状态栏样式content有三个值:default、black、black-translucent
//对移动网站-mobile web进行收藏(“添加到桌面图标”)的时候增加的图标定义属性
//apple-touch-icon:增加高光光亮的图标
//apple-touch-icon-precomposed:设计原图图标
网页针对不同屏幕分辨率修改,用-webkit-device-pixel-ratio这个media标签或在js中用 window.devicePixelRatio这个方法,设置target-densitydpi标签和device-dpi属性。这让你的定制更具有 灵活性。
移动网站的视图的标签
HTML5的data-前缀就被称为data属性
本地存储:
sessionStorage.lastname="Smith";//针对session的存储
localStorage.lastname="Smith";//没有时间限制的本地存储(IE8也支持)
document.write(localStorage.lastname);
使用本地存储前应先确定window.localStorage是否存在
//placeholder:默认提示,required:定义输入的字段是否必须(提交时的非空验证)
HTML5 提供了两种检测是否在线的方式:navigator.online(true/false) 和 online/offline事件。
navigator.standalone为true:从桌面启动
navigator.standalone为false:从ios浏览器启动
localStorage. length:返回现在已经存储的变量数目。
localStorage. key(n):返回第n个变量的键值(key)。
localStorage.getItem(k):和localStorage.k一样,取得键值为k的变量的值。
localStorage.setItem(k , v):和localStorage.k = v一样,设置键值k的变量值。
localStorage.removeItem(k):删除键值为k的变量。
localStorage.clear():清空所有变量。
window.applicationCache对象的事件:
checking: 用户代理检查更新或者在第一次尝试下载manifest文件的时候,本事件往往是事件队列中第一个被触发的
noupdate: 检测出manifest文件没有更新
downloading: 用户代理发现更新并且正在取资源,或者第一次下载manifest文件列表中列举的资源
progress: 用户代理正在下载资源manifest文件中的需要缓存的资源
cached: manifest中列举的资源已经下载完成,并且已经缓存
updateready: manifest中列举的文件已经重新下载并更新成功,接下来js可以使用swapCache()方法更新到应用程序中
obsolete: 1、manifest的请求出现404或者410错误,应用程序缓存被取消 2、manifest的请求出现404或者410错误,更新缓存的请求失败 3、manifest文件没有改变,但是页面引用的manifest 文件没有被正确地下载
error: 1、在取manifest列举的资源的过程中发生致命的错误 2、在更新过程中manifest文件发生变化
<---------------------------------------------------------------CSS---------------->
-moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px;//圆角
text-shadow: 2px 2px 5px #333;//添加阴影
-webkit-user-select: none;//不可先择文字(webkit内核的浏览器)
-webkit-text-size-adjust:none;//苹果移动设备上会识别,用于保证文字大小
变形(transformation)、转换(transition)和动画(animation)
图片旋转的一个样式:
transition_duration{
-webkit-transform:rotate(10deg);
-webkit-transition-property:all; //发生变化的属性
-webkit-transition-duration:0.5s; //发生变化的时间
-webkit-transition-timing-function:ease-in;//定义动画变化的曲线
}
transition_duration:hover{
-webkit-transform:rotate(40deg);
}
transform:旋转、扭曲、缩放、移动、矩阵变形 {transform-origin:元素的基点,默认在元素中心}
transform: rotate(30deg) | scale(2,1.5)(水平,垂直) | skew(30deg,10deg) | translate(100px,20px) |matrix;
<------------------------------------------------------------ajax------------------>
isLocal: true//该请求来自本地计算机
用document.onreadystatechange的方法来监听状态改变,
用document.readyState == “complete”判断是否加载完成
0 - uninitialized (未初始化)还没有调用send()方法
1 - loading (载入)已调用send()方法,正在发送请求
2 - loaded (载入完成)send()方法执行完成,已经接收到全部响应内容
3 - interactive (交互)正在解析响应内容
4 - complete (完成)响应内容解析完成,可以在客户端调用了
<-----------------------------------------------------jQuery js----------------------->
document.getElementById("testButton").addEventListener("click", Go, false);//添加监听事件
window 的DOMContentLoaded事件在形成完成的DOM树之后就会触发,不理会图像、JavaScript文件、CSS文件或其他资源是否已经下载完 毕。与load事件不同,DOMContentLoaded支持在页面下载的早期添加事件处理程序,这也就意味着用户能够尽早地与页面进行交互。(它是火 狐下特有的事件)
document.addEventListener('DOMContentLoaded', loaded, false);//
侦听器在侦听时有三个阶段:捕获阶段(根节点到子节点检查是否调用了监听函数)→、目标阶段(目标本身)→冒泡阶段(目标本身到根节点)。
public override function addEventListener(type(事件类型):String, listener():Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
$(selector).bind(event) //向匹配元素添加一个或更多事件处理器
$(selector).live(event) //向匹配元素添加一个事件处理器,现在或将来
$(selector).die() 移除所有通过 live() 函数添加的事件处理器
$(selector).unbind()移除被选元素的事件处理程序,适用于任何通过 jQuery 附加的事件处理程序
Tmpl提供了几种tag:
${}:等同于{{=}},是输出变量,通过了html编码的。
{{html}}:输出变量html,但是没有html编码,适合输出html代码。
{{if }} {{else}}:提供了分支逻辑。
{{each}}:提供循环逻辑,$value访问迭代变量。
devicePixelRatio:设备像素比,高清iPad下,window.devicePixelRatio为2
(/ipad/gi).test(navigator.appVersion)//判断移动终端的浏览器是否为ipad,navigator.appVersion为浏览器的版本
window.orientation :这个属性给出了当前设备的屏幕方向,0表示竖屏,正负90表示横屏(向左与向右)模式
onorientationchange : 在每次屏幕方向在横竖屏间切换后,就会触发这个window事件,用法与传统的事件类似
页面事件先后顺序:
mobileinit:页面没加载DOM之前事件
pagebeforecreate:页面的DOM加载后,DOM初始化之前触发的事件
pagecreate:在HTML已经在DOM中建立完成,初始化也完成事件
pageinit:页面完全加载完后
触摸事件
三种在规范中列出并获得跨移动设备广泛实现的基本触摸事件:
1. touchstart:手指放在一个DOM元素上。
2. touchmove:手指拖曳一个DOM元素。
3. touchend:手指从一个DOM元素上移开。
每个触摸事件都包括了三个触摸列表:
1. touches:当前位于屏幕上的所有手指的一个列表。
2. targetTouches:位于当前DOM元素上的手指的一个列表。
3. changedTouches:涉及当前事件的手指的一个列表。
例如,在一个touchend事件中,这就会是移开的手指。
这些列表由包含了触摸信息的对象组成:
1. identifier:一个数值,唯一标识触摸会话(touch session)中的当前手指。
2. target:DOM元素,是动作所针对的目标。
3. 客户/页面/屏幕坐标:动作在屏幕上发生的位置。
4. 半径坐标和 rotationAngle:画出大约相当于手指形状的椭圆形。
gesturestart //当两个手指接触屏幕时触发
gesturechange //当两个手指接触屏幕后开始移动时触发
gestureend
onorientationchange //屏幕旋转事件
orientationchange // 检测触摸屏幕的手指何时改变方向
// 隐藏地址栏 & 处理事件的时候 ,防止滚动条出现
addEventListener('load', function(){
setTimeout(function(){ window.scrollTo(0, 1); }, 100);
});
e.preventDefault()//取消事件的默认动作
taphold :长按事件
var myscroll=new iScroll("wrapper",{hScrollbar:false, vScrollbar:false});//定义一滚动对象
hScroll:false 禁止横向滚动 true横向滚动 默认为true
vScroll:false 禁止垂直滚动 true垂直滚动 默认为true
hScrollbar:false 隐藏水平方向上的滚动条
vScrollbar:false 隐藏垂直方向上的滚动条
fixedScrollbar: 在iOS系统上,当元素拖动超出了scroller的边界时,滚动条会收缩,设置为true可以禁止滚动条超出scroller的可见区域。默认在Android上为true, iOS上为false
fadeScrollbar:false 指定在无渐隐效果时隐藏滚动条
hideScrollbar: 在没有用户交互时隐藏滚动条 默认为true
bounce: 启用或禁用边界的反弹,默认为true
momentum: 启用或禁用惯性,默认为true,此参数在你想要保存资源的时候非常有用
lockDirection:false 取消拖动方向的锁定, true拖动只能在一个方向上(up/down 或者left/right)
zoom:true 滚动对象可以放大缩小
zoomMax: 指定允许放大的最大倍数,默认为4
onScrollEnd:在滚动完成后的回调
x:滚动水平初始位置
y:滚动垂直初始位置
bounce:true,是否超过实际位置反弹
bounceLock:false,当内容少于滚动是否可以反弹,这个实际用处不大
momentum:true,动量效果,拖动惯性
lockDirection:true,当水平滚动和垂直滚动同时生效时,当拖动开始是否锁定另一边的拖动
useTransform:true,是否使用CSS形变
useTransition:false,是否使用CSS变换
topOffset:0,已经滚动的基准值(一般情况用不到)
checkDOMChanges:false,是否自动检测内容变化
【注意事项】:如果想要图片缩放的效果很好的话要把他们放到硬件的合成层中。通俗点说,就是在所有需要缩放的img元素上使用-webkit- transform:translate3d(0,0,0)来实现,而且尤为重要的是,硬件的加速会占用大量资源,要谨慎使用,否则你的应用可能就此崩 溃。
document.createElement()是在对象中创建一个对象,要与appendChild() 或 insertBefore()方法联合使用。其中,appendChild() 方法在节点的子节点列表末添加新的子节点。insertBefore() 方法在节点的子节点列表任意位置插入新的节点。
var board = document.getElementById("board");
var e = document.createElement("input");
e.type = "button";
e.value = "这是测试加载的小例子";
var object = board.appendChild(e);
encodeURI()//编码
decodeURI()//解码
标签属性:
src:视频的URL
poster:视频封面,没有播放时显示的图片
preload:预加载
autoplay:自动播放
loop:循环播放
controls:浏览器自带的控制条
width:视频宽度
height:视频高度
停止:
myVideo.currentTime = 0;
myVideo.pause();
浏览器的渲染和操作顺序大致如下:
HTML解析完毕
外部脚本和样式表加载完毕
脚本在文档内解析并执行
HTML DOM完全构造起来
图片和外部内容加载
网页完成加载
<--------------------tmpl替换-------------------------->
news_template = $('#news_template').template();
$.tmpl(news_template, manufacture_news).appendTo('#news_content');
var html = $("#news_content").html();
if (html.indexOf("[br]") > -1)
{
html = html.$replace("[br]", " ");
html = html.$replace("<", "<").$replace(">", ">");
$("#news_content").html(html);
}
${Title} ${CreateTime}
${Content}
------------------数据库优化---------------------
A、数据类型尽量用数字型,数字型的比较比字符型的快很多。
B、 数据类型尽量小,这里的尽量小是指在满足可以预见的未来需求的前提下的。
C、 尽量不要允许NULL,除非必要,可以用NOT NULL+DEFAULT代替。
D、少用TEXT和IMAGE,二进制字段的读写是比较慢的,而且,读取的方法也不多,大部分情况下最好不用。
E、 自增字段要慎用,不利于数据迁移。
系统设计阶段应该归纳一些业务逻辑放在数据库编程实现,数据库编程包括数据库存储过程、触发器和函数。用数据库编程实现业务逻辑的好处是减少网络流量并可更充分利用数据库的预编译和缓存功能。
----------
索引的设计
在设计阶段,可以根据功能和性能的需求进行初步的索引设计,这里需要根据预计的数据量和查询来设计索引,可能与将来实际使用的时候会有所区别。
关于索引的选择,应改主意:
A、 根据数据量决定哪些表需要增加索引,数据量小的可以只有主键。
B、 根据使用频率决定哪些字段需要建立索引,选择经常作为连接条件、筛选条件、聚合查询、排序的字段作为索引的候选字段。
C、 把经常一起出现的字段组合在一起,组成组合索引,组合索引的字段顺序与主键一样,也需要把最常用的字段放在前面,把重复率低的字段放在前面。
D、 一个表不要加太多索引,因为索引影响插入和更新的速度。
注意SELECT INTO后的WHERE子句,因为SELECT INTO把数据插入到临时表,这个过程会锁定一些系统表,如果这个WHERE子句返回的数据过多或者速度太慢,会造成系统表长期锁定,诸塞其他进程。
A、 控制同一语句的多次执行,特别是一些基础数据的多次执行是很多程序员很少注意的。
B、 减少多次的数据转换,也许需要数据转换是设计的问题,但是减少次数是程序员可以做到的。
C、 杜绝不必要的子查询和连接表,子查询在执行计划一般解释成外连接,多余的连接表带来额外的开销。
---------尖角代码
手机版网站起码要实现一些基本的功能吧:
1.页面的适用性问题。对于移动终端,有不一样的分辨率与屏幕尺寸,如果还像电脑端的设计还限制网页的宽度为1003px或其他像素值,字体大小 还用12px或14px,那么,不一样的终端的效果差别会很大。所以这里,最好让网页的宽度自适应屏幕,还好,w3c在设计html的时候为我们考虑了这 一点,只需一句话,就可以搞定,就是加上
Javascript代码
[javascript]
view plain
copy
print ?
"viewport"
content=
"width=device-width"
/>
,对于字体的话,我们就用em或ex为单位就好
2.版本制作问题。移动页面往往针对不同的手机设置不同的版本,一般有精简版,标准版,3G版,触屏版,智能手机版等等,这些除了在页面设计上有 不同外,页面语言也会不同的。精简版采用wap 1.0 的wml脚本编写,这个通用性以前很强,很多国产手机都支持这个语言的,但这个语言是很精简的。标准版的一般可以采用wap 2.0技术,对应的脚本语言是xhtml mp(xhtml mobile profile),这个语言是xhtml的子集,这个并且支持大部分的css,基本上和电脑版的差不多,但一般不能用js,这是考虑到这些手机是不支持 js的。对于智能手机版,由于现在的智能手机都支持js,这个版本的制作上就简单多了,不过,又由于大部分智能手机(基本上除去塞班手机,包括 Android,ios,wp7等)都支持Html5,因此,智能手版可以采用html5来制作。
3.版本控制问题。可能这部分是比较不好解决的,怎么智能判断手机的最佳版本并跳转,可以从这几个方面考虑。一方面,可以想办法得到手机的操作系 统,比如,Android的,ios的,就可以跳转到html5版了,windows系统,毫无疑问电脑版,获得手机系统,可能通过得到手机型号,现在的 方法是通过浏览器的UA(user agent),获得手机的一些信息,简单一点的,直接可以通过UA判断手机的制造产商。要想获得更多的信息,就得有一个数据库,因为不同手机型号会有不一 样的UA信息,世界上的手机有很多,自己要想做一个这样的数据库还是很难的,不过,已经有人为我们做好了这样的数据库,或者更方便的,做好了一个识别手机 适用最佳版本的函数库,这里我推荐用Wurfl。另一方面,可以通过页面的脚本来判断浏览器对js和html5的支持,代码如下
Javascript代码
版本控制
普通版
[javascript]
view plain
copy
print ?
"1.0"
encoding=
"UTF-8"
?>
"-//WAPFORUM//DTD XHTML Mobile 1.0//EN"
"http://www.wapforum.org/DTD/xhtml-mobile10.dtd"
>
"http://www.w3.org/1999/xhtml"
>
"Content-Type"
content=
"text/html; charset=utf-8"
/>
"viewport"
content=
"width=device-width"
/>
版本控制
"text/javascript"
>
window.onload =
function
(){
try
{
document.getElementById(
"c"
).getContext(
"2d"
);
document.location =
'支持html5版的链接'
;
}
catch
(e){
document.location =
'支持js版'
;
}
};
'c'
>
普通版
如果你仅仅想开发一个版本,只是判断一下是不是移动客户端,这里引用一段discuz! x2的代码
Php代码
function checkmobile() {
global $_G;
$mobile = array();
static $mobilebrowser_list =array('iphone', 'android', 'phone', 'mobile', 'wap', 'netfront', 'java', 'opera mobi', 'opera mini',
'ucweb', 'windows ce', 'symbian', 'series', 'webos', 'sony', 'blackberry', 'dopod', 'nokia', 'samsung',
'palmsource', 'xda', 'pieplus', 'meizu', 'midp', 'cldc', 'motorola', 'foma', 'docomo', 'up.browser',
'up.link', 'blazer', 'helio', 'hosin', 'huawei', 'novarra', 'coolpad', 'webos', 'techfaith', 'palmsource',
'alcatel', 'amoi', 'ktouch', 'nexian', 'ericsson', 'philips', 'sagem', 'wellcom', 'bunjalloo', 'maui', 'smartphone',
'iemobile', 'spice', 'bird', 'zte-', 'longcos', 'pantech', 'gionee', 'portalmmm', 'jig browser', 'hiptop',
'benq', 'haier', '^lct', '320x320', '240x320', '176x220');
$useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
if(($v = dstrpos($useragent, $mobilebrowser_list, true))) {
$_G['mobile'] = $v;
return true;
}
$brower = array('mozilla', 'chrome', 'safari', 'opera', 'm3gate', 'winwap', 'openwave', 'myop');
if(dstrpos($useragent, $brower)) return false;
$_G['mobile'] = 'unknown';
if($_GET['mobile'] === 'yes') {
return true;
} else {
return false;
}
}
function dstrpos($string, &$arr, $returnvalue = false) {
if(emptyempty($string)) return false;
foreach((array)$arr as $v) {
if(strpos($string, $v) !== false) {
$return = $returnvalue ? $v : true;
return $return;
}
}
return false;
}
var_dump(checkmobile());//如果是移动端返回true,否则false
[php]
view plain
copy
print ?
function
checkmobile() {
global
$_G
;
$mobile
=
array
();
static
$mobilebrowser_list
=
array
(
'iphone'
,
'android'
,
'phone'
,
'mobile'
,
'wap'
,
'netfront'
,
'java'
,
'opera mobi'
,
'opera mini'
,
'ucweb'
,
'windows ce'
,
'symbian'
,
'series'
,
'webos'
,
'sony'
,
'blackberry'
,
'dopod'
,
'nokia'
,
'samsung'
,
'palmsource'
,
'xda'
,
'pieplus'
,
'meizu'
,
'midp'
,
'cldc'
,
'motorola'
,
'foma'
,
'docomo'
,
'up.browser'
,
'up.link'
,
'blazer'
,
'helio'
,
'hosin'
,
'huawei'
,
'novarra'
,
'coolpad'
,
'webos'
,
'techfaith'
,
'palmsource'
,
'alcatel'
,
'amoi'
,
'ktouch'
,
'nexian'
,
'ericsson'
,
'philips'
,
'sagem'
,
'wellcom'
,
'bunjalloo'
,
'maui'
,
'smartphone'
,
'iemobile'
,
'spice'
,
'bird'
,
'zte-'
,
'longcos'
,
'pantech'
,
'gionee'
,
'portalmmm'
,
'jig browser'
,
'hiptop'
,
'benq'
,
'haier'
,
'^lct'
,
'320x320'
,
'240x320'
,
'176x220'
);
$useragent
=
strtolower
(
$_SERVER
[
'HTTP_USER_AGENT'
]);
if
((
$v
= dstrpos(
$useragent
,
$mobilebrowser_list
, true))) {
$_G
[
'mobile'
] =
$v
;
return
true;
}
$brower
=
array
(
'mozilla'
,
'chrome'
,
'safari'
,
'opera'
,
'm3gate'
,
'winwap'
,
'openwave'
,
'myop'
);
if
(dstrpos(
$useragent
,
$brower
))
return
false;
$_G
[
'mobile'
] =
'unknown'
;
if
(
$_GET
[
'mobile'
] ===
'yes'
) {
return
true;
}
else
{
return
false;
}
}
function
dstrpos(
$string
, &
$arr
,
$returnvalue
= false) {
if
(
empty
(
$string
))
return
false;
foreach
((
array
)
$arr
as
$v
) {
if
(
strpos
(
$string
,
$v
) !== false) {
$return
=
$returnvalue
?
$v
: true;
return
$return
;
}
}
return
false;
}
var_dump(checkmobile());
4.手机版本的大小问题。一般来说,对于精简版和普通版的手机网页,我们是做得越精简越好,能省的代码最好省去,毕竟现在手机流量对用户来说还是 很宝贵的。比如元素命名,一般页面少的话,命名越短越好,css最好写在一行。css中,有些元素是继承父类的样式的,不用重复定义,善用默认值。
5.浏览器缓存。如果再更新不快的情况下,最好开启浏览器缓存