前端开发规范

来源:互联网 发布:txt阅读器 for mac 编辑:程序博客网 时间:2024/06/16 11:28

前端开发规范

前端开发

1、HTML规范

1.1.使用正确的HTML5文档类型

  1. <!doctype html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="renderer" content="webkit"> <!-- 360使用极速模式渲染 -->
  6. <title>Document</title>
  7. </head>
  8. <body>
  9. </body>
  10. </html>

1.2 兼容的meta属性

  1. <meta name="renderer" content="webkit"> <!-- 360使用极速模式渲染 -->

1.3 统一使用4空格的tab缩进

1.4.避免不规范的元素嵌套

错误示例:

  1. <ul>
  2. <div>导航栏标题</div>
  3. <li>子项1</li>
  4. <li>子项2</li>
  5. <ul>

正确示例:

  1. <div>导航栏标题</div>
  2. <ul>
  3. <li>子项1</li>
  4. <li>子项2</li>
  5. <ul>

ul标签只允许存在li作为其直接子标签。错误示例中的代码虽然可以正常渲染,但是由于不同浏览器容错机制不一致,错误的示例代码可能会导致额外的hack。

1.5.自定义属性采用data-*格式

错误示例:

  1. <div ng-click="click()">

正确示例:

  1. <div data-ng-click="click()">

data-*是HTML5的标准规范,如不采用data-*格式,IDE会显示警告信息,避免警告信息影响正常的debug,建议采用data-*格式自定义属性。

1.6.布尔类型的属性,建议不添加属性值

错误示例:

  1. <input type="checkbox" checked="true">
  2. <input type="checkbox" checked="flase">
  3. <input type="checkbox" checked="checked">

正确示例:

  1. <input type="checkbox" checked>

获取选择选中状态,使用dom节点对象的checked属性,或者jQuery的is方法,不要使用attr('checked')进行判断。

错误做法:

  1. var $checkbox = $('input[checkbox]');
  2. $checkbox.attr("checked"); // 不准确,甚至会取得非预期值

正确做法:

  1. $checkbox.is(':checked');
  2. $checkbox.check = true;
  3. $checkbox.check;

2、CSS规范

2.1.确定全局唯一的元素,可以使用id,否则使用class

否则会导致后期维护成本过大。

2.2.选择器应尽量避免嵌套,最多不过3级别

不好的做法:

  1. body #container .head .title {
  2. // code here
  3. }

推荐做法:

  1. .h-title {
  2. // code here
  3. }

嵌套过多,会导致css权重过大,子class跟父class紧耦合,后期维护成本大。

3、JavaScript规范

3.1.字符串统一使用单引号包含

不好的示例:

  1. var msg = "Hello JavaScript!";

正确示例:

  1. var msg = 'Hello JavaScript!';

使用单引号的最主要原因是,避免额外的单引号\双引号转义。

  1. var dom = “<div data-ng-click=\"click();\">双引号\"\"不建议</div>”;

vs

  1. var dom = '<div data-ng-click="click();">双引号""不建议</div>';

两种写法对比,优劣一目了然。

3.2.避免使用JavaScript拼接HTML

使用JavaScript拼接HTML,会有以下问题: 
* 极容易产生XSS漏洞; 
* 关注点不分离,升级维护极其困难; 
* 开发效率低下,代码不健壮,非常容易产生bug; 
* Debug变的异常艰难;

不好的示例:

  1. var names = ['tiger','apple', '<script>alert("xss");</script>'];
  2. var dom = '<ul>';
  3. names.forEach(function(name,index){
  4. dom += '<li>' + name + '</li>';
  5. })
  6. dom += '</ul>';
  7. $('body').html(dom);

上面的代码会导致一下问题: 
* names[2]插入页面后,<script>alert("xss");<script>会被当成脚本执行,容易被用户利用,入侵系统; 
* 代码升级维护困难,如果要修改样式,或者渲染的对象更加复杂(多层嵌套),维护这样的代码不仅效率低下,容易出错,简直就是噩梦; 
* 产生bug的情况下,调试异常复杂;

正确示例:

AngularJS写法:

  1. <ul>
  2. <li data-ng-repeat="name in names">{{ name }}</li>
  3. </ul>

如果使用jQuery情况下,可以使用前端模板引擎,例如doT.js、jQuery Template等。

3.3 JavaScript语法技巧

使用这些小技巧,可以让代码更加简洁、容易理解。

3.3.1 默认参数赋值

冗长写法:

  1. function fun(param) {
  2. if(param == null) {
  3. param = {name:'tiger'};
  4. }
  5. }

简洁写法:

  1. function fun(param) {
  2. param = param || {name:'tiger'};
  3. }

3.3.2 判空执行

冗长写法:

  1. function fun() {
  2. if(flag) {
  3. callback();
  4. }
  5. }

简洁写法:

  1. function fun() {
  2. flag && callback();
  3. }

3.3.3 自调用函数

冗长写法:

  1. function fun(){
  2. // code here
  3. }
  4. fun();

简洁写法:

  1. (function(){
  2. // code here
  3. })();

3.3.4 数组迭代

冗长写法:for

简洁写法:filter、some、every、forEach、map

3.3.4.2 filter:对数组进行过滤,并返回新的数组
  1. var s = [1,2,3,4,5];
  2. var ns = s.filter(function(item,index) {
  3. return item > 3;
  4. })
  5. console.log(ns); // [4,5]
3.3.4.3 some:判断数组中是否有符合条件的元素
  1. var s = [1,2,3,4,5];
  2. var b = s.some(function(item,index) {
  3. return item > 3;
  4. })
  5. console.log(b); // true
3.3.4.4 every:判断数组中所有元素是否都符合条件
  1. var s = [1,2,3,4,5];
  2. var b = s.every(function(item,index) {
  3. return item > 3;
  4. })
  5. console.log(b); // false
3.3.4.5 map:对数组中的元素进行处理,并返回新的数组
  1. var s = [1,2,3,4,5];
  2. var ns = s.map(function(item,index) {
  3. return item * 2;
  4. })
  5. console.log(ns); // [2,4,6,8,10]
3.3.4.6 forEach:迭代数组元素
  1. var s = [1,2,3,4,5];
  2. var ns = s.map(function(item,index) {
  3. console.log(item); // 依次打印1,2,3,4,5
  4. })

3.4. 前端开发的JavaScript技巧

3.4.1 使用Angular时,ajax请求请使用ng自带的$http,避免使用jQuery的ajax

$http的ajax回调会自动更新DOM节点,而jQuery的回调没有这个特征,需要手动apply。

  1. <div>{{ user.username }}</div>

正确的jQuery写法:

  1. $.post('/login',{username:'tiger',passwd='123456'},function(rs){
  2. $scope.user = rs.user;
  3. $scope.$apply();
  4. })

正确的AngularJS写法:

  1. var params = {username:'tiger',passwd='123456'}
  2. $http({method : 'POST',url : '/login', data: $.param(params)
  3. }).then(function(rs) {
  4. $scope.user = rs.data.user;
  5. });

如果是GET请求,data则改成params,同时不需要$.param序列化,params的参数放url上,而data是放request body中。

  1. var params = {username:'tiger',passwd='123456'}
  2. $http({method : 'GET',url : '/login', params: params
  3. }).then(function(rs) {
  4. $scope.user = rs.data.user;
  5. });

3.4.2 HTTP请求中,获取使用GET,提交、修改和删除使用POST

这样更加符合REST的语义,如果POST使用GET代替,在开发阶段就难以调试,而且无法使用GET的特性进行一系列调优,例如缓存等。

HTTP中,GET/POST/DEL等的区别:http://www.cnblogs.com/zhangpengshou/archive/2012/07/09/2583096.html

3.4.3 获取ajax的表单参数,jQuery可以将form表单序列化,Angualr可以绑定对象

推荐的jQuery写法:

  1. <form id="loginFrom">
  2. <input name="username" type="text" />
  3. <input name="password" type="passwrod"/>
  4. </form>
  5. <script>
  6. var params = $('#loginForm').serialize();
  7. $.post('/login',params,function(rs){
  8. // callback
  9. });
  10. </script>

推荐的AngularJS写法:

  1. <form>
  2. <input type="text" data-ng-model="loginForm.username" />
  3. <input type="passwrod" data-ng-model="loginForm.password"/>
  4. </form>
  5. <script>
  6. $http({
  7. method : 'POST',
  8. url : '/login',
  9. data: $.param($scope.loginForm)
  10. }).then(function(rs) {
  11. // callback
  12. });
  13. </script>

3.4.4 jQuey调用AngularJS的方法

思路:取得AngularJS作用域下的节点找到scope,通过scope调用方法:

  1. var container = $('#container'); // #containe要在data-ng-app的子节点下
  2. angular.element(container).scope().fun(); // 调用AngularJS下面的fun方法;

强烈推荐使用Angular开发,jQuery的功能基本95%以上都可以用Angular代替,代码量更少,更容易维护。

4、AngularJS与JAVA EnumMap实现前后端统一

  1. public enum ChargeControlMode {
  2. BMS("bms", Constant.CHARGE_CONTROL_MODE_BMS),
  3. POWER("power", Constant.CHARGE_CONTROL_MODE_POWER),
  4. MONEY("money", Constant.CHARGE_CONTROL_MODE_MONEY),
  5. TIME("time", Constant.CHARGE_CONTROL_MODE_TIME);
  6. ...
  7. public static Map<String, String> buildEnumElementMap() {
  8. Map<String, String> chargeControlModeMap = new HashMap<String, String>();
  9. chargeControlModeMap.put(ChargeControlMode.BMS.name(), Constant.CHARGE_CONTROL_MODE_BMS);
  10. chargeControlModeMap.put(ChargeControlMode.POWER.name(), Constant.CHARGE_CONTROL_MODE_POWER);
  11. chargeControlModeMap.put(ChargeControlMode.MONEY.name(), Constant.CHARGE_CONTROL_MODE_MONEY);
  12. chargeControlModeMap.put(ChargeControlMode.TIME.name(), Constant.CHARGE_CONTROL_MODE_TIME);
  13. return chargeControlModeMap;
  14. }
  15. }
  1. @SuppressWarnings("rawtypes")
  2. @RequestMapping(value = "/buildAllEnumsMap", method = RequestMethod.GET)
  3. public ResponseEntity<Map<String, Map>> buildAllEnumsMap() {
  4. Map<String, Map> map = buildEnumElementsMap();
  5. if (map.isEmpty()) {
  6. return new ResponseEntity<Map<String, Map>>(HttpStatus.NO_CONTENT);
  7. }
  8. return new ResponseEntity<Map<String, Map>>(map, HttpStatus.OK);
  9. }
  10. /**
  11. * 构造充电桩参数相关的枚举元素类型的Map<String, Map><br>
  12. * key->枚举类型的名称,如BillingType<br>
  13. * vale-> 是一个Map,包含枚举类型的所有元素,key是枚举元素名称的变量,value是具体值<br>
  14. * @return 返回充电桩参数相关的枚举类型Map<String, Map>
  15. */
  16. @SuppressWarnings("rawtypes")
  17. private Map<String, Map> buildEnumElementsMap() {
  18. Map<String, Map> map = new HashMap<String, Map>();
  19. //计费方式
  20. map.put(BillingType.class.getSimpleName(), BillingType.buildEnumElementMap());
  21. //充电控制模式
  22. map.put(ChargeControlMode.class.getSimpleName(), ChargeControlMode.buildEnumElementMap());
  23. return map;
  24. }
  1. that.buildAllEnumsMap = function(){
  2. $.eompTools.blockUI();
  3. $.eompAjaxService.doGet('/em/rest/stakeParm/buildAllEnumsMap', {}, function(resdata) {
  4. if (resdata) {
  5. that.enumsMap = resdata;
  6. }
  7. $.eompTools.unblockUI();
  8. });
  9. };
  10. <label class="col-md-4 control-lable" for="file"> 控制模式: </label>
  11. <span class="col-md-6 control-lable" for="file">
  12. {{ctrl.enumsMap.ChargeControlMode[ctrl.parameters.chargeConfig.chargeControlMode]}}
  13. 等价于
  14. {{ctrl.enumsMap.ChargeControlMode['TIME']}}
  15. </span>
  16. ==> 控制模式:时间控制
原创粉丝点击