Batsing的网页编程规范(HTML/CSS/JS/PHP)
特别注意!!!我这里的前端编程规范不苟同于Bootstrap的前端规范。
因为我和它的目的不同,Bootstrap规范是极简主义,甚至有些没有考虑到兼容性的问题。
我的规范是自己从编程实践中总结出来的,每条都附有详细原因,不喜者请评论阐明原因。
1、HTML基本元素、标签规范
闭合(<p></p>)、自闭合(<br />)、小写(<INPUT />)
1)不闭合的标签往往会导致非常多异常的页面显示,<div>标签不匹配、漏配这种情况尤其常见,建议div一定要对齐不要左一格右一格的,使用智能方便的IDE,可以方便地看到各个标签的匹配情况。
2)这里的规范自闭合标签要写 /,而Bootstrap中的说法是不写,我的理由如下:
1.XHTML和XML规范;
2.我记得在某本书说过不写/,某些标签在某些低版本的IE中会出现兼容问题,这个我不太记得清楚了,而且规范的写法是 “空格+斜线”;
3.IDE会自动补全,没必要又去手工改一下;(在此推荐一下下HBuilder IDE 和 emmet插件)
4.ReactJS中的规范是要加上 / ,不然标签会识别不了;
5.如果你期望 XML 软件使用你的页面,使用这种风格是非常好的。
3)标签和属性小写,那是因为网上几乎所有的资料和代码都是用小写的,突然弄个大写除了特立独行之外并没有任何用处,但会让别人看得不爽。
2、HTML属性
小写(ID="..."),双引号(id='...' 特殊情况可用单引号),
特殊情况示范:
<div onclick='payOrder("x2015090901353456");' ></div>
属性顺序(这里的顺序与Bootstrap规范有很大出入,我附上解释)
input标签方面:
type(input标签) > name(input标签) > id > value(input标签) > ... > class > style > onclick,onfoucus,on...
最首要的是确定输入类型,是文本、单选、多选、按钮、文件、提交……;
次之是确定name和id,因为直接提交表单时传值的key就是name,而用ajax提交时可以用name(节俭)也可以用id(JS执行快)来读取值;
再次则是value,一般是有设置默认值才添加这个属性,有默认值要醒目显示出来,调试时发现没有默认值或者默认值异常则可以快速找出来;
data-*,role等等其它属性直接放在中间,因为一般一次写好了就基本上不需要动的了,class属性也是同理;
style属性放在几乎最后,是因为可能一些比较独立的DOM有自己的样式,而且也可能经常变动,放在最后(如果没有绑定事件则是最后)比较显眼;
onclick等on...方法,因为IOS一些网页动态加载的DOM使用jquery的live也可能会有无法绑定事件的问题,所以经常要绑定某些事件的会直接使用on……属性,这个放在最后也是因为显眼的原因,因为它有绑定事件,所以要一眼就能看得出来,而一眼看得出来的除了最开头及第二就剩最后了。
img标签:
src(img标签)>width/height(img标签)>alt(img标签)> id>... > class > style > onclick,onfoucus,on...
最首要的当然是图片的源地址,这个不用解释了吧;
次之是图片的宽度或高度,注意是“或”,这两个属性建议一般只设置一个,因为设置一个另一个则会自动比例适应,而设定两个则会使不合尺寸的图片拉伸;
alt是图片提示,个人感觉如果是手机端则需要写,PC端一般不用写不,因为很多时候手机会调成无图模式以节省流量,电脑则无需;
后面的属性顺序原理同上;
!以上顺序如与IDE自动补全不太一致,则以IDE自动补全的为优先考虑。(一般是Emmet插件)
!如有不同意见,请以浏览器审查元素看到的排序为准
3、表单
使用 label 标签包装 单选、多选、下拉等元素,扩大用户点击范围到文字;
不建议使用for-id的方法绑定label,因为id是稀有资源不宜为太多表单分配过多id,表单使用name就足够了;
form 在需要从服务器读取原来的数据的要加 autocomplete="off",以免火狐浏览器的自动记录替换代码设定的默认值。
4、CSS颜色#
在PC版网页中不要使用缩写形式(如:#aaa),要写完整(#aaaaaa),否则IE8及以下不能识别而变成黑色;
5、JS中所有变量都要用var显式声明
JS中,默认情况下,没有显示声明的变量为全局变量。对于只需要在函数内使用的变量来说,不用var声明会使变量变成全局变量,变量在函数使用完后得不到释放,造成内存的浪费;最主要是这些变量很可能在其它函数中重名,可能会造成各种奇奇怪怪的问题。对于全局变量来说,在外部用var显示声明,可以明确地指出有地方用了全局变量,以便与函数中的参数变量区分,便于日后维护和优化。
6、JS勿用 eval() 函数
解析JSON字符串请使用jQuery的$.parseJSON函数,手机网页也可直接使用原生的 JSON.parse() 函数,或者直接在服务端直接返回json对象,设置mime type(如Thinkphp的ajaxReturn()函数)。因为eval()函数是把字符串作为脚本运行的意思,非常危险,非常容易产生CSRF攻击隐患!
7、请使用UTF8无BOM编码格式
因为很多后台编程语言如PHP只支持utf8编码的JSON,为避免频繁的转编码,请所有文档都使用utf8格式;
无BOM就是为了避免session、cookie、GD库生成的图片等出现不正常;
另外注意IE7及以下的JSON不能带多余的逗号,比如 {"name":"batsing", "age":"24", } 最后多出那个的,是会报错的;
8、用Tab而不是用空格
详细原因查看我的另一篇博文。
附CodeIgniter(一个PHP框架)的PHP编程规范“在代码中使用制表符(tab)来代替空格,这虽然看起来是一件小事,但是使用制表符代替空格, 可以让开发者阅读你代码的时候,可以根据他们的喜好在他们的程序中自定义缩进。 此外还有一个好处是,这样文件可以更紧凑一点,也就是本来是四个空格字符, 现在只要一个制表符就可以了。”。原文链接
9、JS中的方法不需要写 window.
比如 window.location.href、window.document.getElement...、 这些都不需要写前面的 window. 更多详情参考 菜鸟教程的BOM章节>>
10、该加的meta标记不要省
移动端有哪些meta,PC端有哪些meta,请见我的博文 前端手札--meta标记篇
11、巧用title属性
在一些管理后台,一些比较隐蔽的操作以及操作图标上使用title属性会有很大的提示作用。比如ECshop的管理后台中就有大量这种例子
12、拦截表单提交使用 preventDefault() 而不是 return false
在一些网页尤其是后台管理页面中,经常需要拦截表单的提交跳转而是转换为Ajax提交。大多数做法是
$("#aForm").submit(function(){ //这里做一些处理和AJAX提交什么的 return false; //这样阻止浏览器的默认提交跳转 });
但是这个代码里面只要在submit的回调函数里面有任何报错,页面都会立刻跳转,而你却无法看到报了什么错误,对调试非常不便。我受到 <a> 标签跳转可以使用 preventDefault() 来拦截的启发,把它也应用到表单非跳转提交里面来,这样无论里面是否报错都不会造成页面跳转了。
$("#aForm").submit(function( e ){ e.prevenDefault(); //先阻止浏览器默认跳转行为 //这里做一些处理和AJAX提交什么的,有报错也不用怕它会跳转走了 });
11、PHP各版本注意事项
5.3及以前版本有个magic_quotes_gpc,会对所有输入(GET、POST等)进行过滤,时而会造成混乱,如POST一个JSON字符串而双引号被转换了。此功能5.4后移除了,建议5.3及以前版本也将其关闭,避免不必要的麻烦。输入过滤这种事情还是让框架来做比较合理,因为这样可以代码控制不同的过滤规则。
5.4及之后才支持 [] 这种形式的数组,5.3及之前只能使用 array() 。所以如果是使用5.3及以上版本,建议升级到更新版本。
5.3相比5.2更改了很多内容,两者的兼容性可以看做断层了,有旧项目在运行的5.2,不建议升级PHP。而大多数现代PHP框架都会起码要求5.3以上版本,所以在租用云主机和虚拟空间特别留意。
12、PHP中的函数与方法概念区分
函数:函数定义在类外,函数是公共的,都可以使用,一般为小写字母加下划线写法;
方法:方法定义在类内,类的方法可以设定访问权限,需要通过对象或者类来调用,一般为驼峰写法;
13、{ 不要另起一行
有些人喜欢把 { 另起一行,不知道是为了逼格还是什么,但是这样做有什么坏处吗?还真有!
这样会快速增加代码的行数,而且是虚无的行数,这样的后果就是你要更频繁地滚动屏幕,影响代码阅读、人工寻找的效率
而按照K&B风格规范来说,类和方法/函数的左括号另起一行,if/else、switch/case等的左括号放在同一行。
目前所看到的是(从OAuth示例中看到),微信团队用的是K&B风格,而阿里支付宝和新浪微博用的是不另起行,最后这里的总结主要是PHP,而并非前端。
14、类和方法的注释说明文档规范
/** * 实例化多层控制器 格式:[资源://][模块/]控制器 * @param string $name 资源地址 * @param string $layer 控制层名称 * @param integer $level 控制器层次 * @return Controller|false */ function A($name,$layer='',$level='') { ... ... }
因为这种写法是IDE自动生成帮助文档的标准格式,见下图(图截自HBuilder,示范代码A()函数为Thinkphp)。
15、使用Thinkphp框架的项目,参考这篇博文中的该框架专用的规范>>
16、PHP中if、switch等的大号括的写法
在纯PHP文件中,if/else,switch/case,for,while,foreach等使用大括号的形式;
在模板文件中,由于代码大部分是HTML标签,所以中间嵌入的PHP代码 if、switch、for、while、foreach 等不使用大括号,而是使用冒号和endif、endswitch、endfor、endwhile、endforeach 这种形式,这样可以避免大括号嵌套过于复杂造成阅读困难,和嵌套错误等。
<?php if(...): ?> <div>...</div> <?php else: ?> <div>...</div> <?php endif; ?>
17、用protected而不是private修饰
private修饰为私有的意思,但不能被子类继承。在业务扩展,需求更改频繁的现代社会,绝大多数的类,被继承是迟早的事情。一些因为安全等方面原因不宜被访问的方法,应该定义为protected而不是private,以免以后继承时发现一些方法并没有继承过来。在PHP中,方法的public修饰应该被省略,方法默认情况下已经是public,不需要啰嗦地声明。
18、区别使用 return 和 exit
exit会结束整个的PHP脚本。在框架中,都是执行完业务逻辑再分析调试信息的。如果使用exit,业务执行完了但是调试信息不会生成,会让调试带来不便。
但在初始化函数(__construct 和 ThinkPHP的_initialize)中,用exit的地方并不能使用return,因为return只是返回了初始化函数,后面的业务代码还是会继续执行。