前端开发规范

前端开发规范

1.HTML规范

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

<!doctype html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8" />
    <meta name="renderer" content="webkit"> <!-- 360使用极速模式渲染 -->
    <title>Document</title>
</head>
<body>
    
</body>
</html>

1.2 兼容的meta属性

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

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

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

错误示例:

<ul>
    <div>导航栏标题</div>
    <li>子项1</li>
    <li>子项2</li>
<ul>

正确示例:

<div>导航栏标题</div>
<ul>
    <li>子项1</li>
    <li>子项2</li>
<ul>

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

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

错误示例:

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

正确示例:

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

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

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

错误示例:

<input type="checkbox" checked="true">
<input type="checkbox" checked="flase">
<input type="checkbox" checked="checked">

正确示例:

<input type="checkbox" checked>

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

错误做法:

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

正确做法:

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

2.CSS规范

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

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

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

不好的做法:

body #container .head .title {
    // code here
}

推荐做法:

.h-title {
    // code here
}

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

3.JavaScript规范

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

不好的示例:

var msg = "Hello JavaScript!";

正确示例:

var msg = 'Hello JavaScript!';

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

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

vs

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

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

3.2.避免使用JavaScript拼接HTML

使用JavaScript拼接HTML,会有以下问题:

  • 极容易产生XSS漏洞;
  • 关注点不分离,升级维护极其困难;
  • 开发效率低下,代码不健壮,非常容易产生bug;
  • Debug变的异常艰难;

不好的示例:

var names = ['tiger','apple', '<script>alert("xss");</script>'];
var dom = '<ul>';
names.forEach(function(name,index){
    dom += '<li>' + name + '</li>';
})
dom += '</ul>';

$('body').html(dom);

上面的代码会导致一下问题:

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

正确示例:

AngularJS写法:

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

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

3.3 JavaScript语法技巧

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

3.3.1 默认参数赋值

冗长写法:

function fun(param) {
    if(param == null) {
        param = {name:'tiger'};
    }
}

简洁写法:

function fun(param) {
    param = param || {name:'tiger'};
}

3.3.2 判空执行

冗长写法:

function fun() {
    if(flag) {
        callback();
    }
}

简洁写法:

function fun() {
    flag && callback();
}

3.3.3 自调用函数

冗长写法:

function fun(){
    // code here
}
fun();

简洁写法:

(function(){
    // code here
})();

3.3.4 数组迭代

冗长写法:for

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

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

3.4. 前端开发的JavaScript技巧

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

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

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

正确的jQuery写法:

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

正确的AngularJS写法:

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

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

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

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写法:

<form id="loginFrom">
    <input name="username" type="text" />
    <input name="password" type="passwrod"/>
</form>
<script>
    var params = $('#loginForm').serialize();
    $.post('/login',params,function(rs){
        // callback
    });
</script>

推荐的AngularJS写法:

<form>
    <input type="text" data-ng-model="loginForm.username" />
    <input type="passwrod" data-ng-model="loginForm.password"/>
</form>
<script>
    $http({
        method : 'POST',
        url : '/login', 
        data: $.param($scope.loginForm)
    }).then(function(rs) {
        // callback说
    });
</script>

3.4.4 jQuey调用AngularJS的方法

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

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

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

JavaScript的String添加了个encodeHTML方法,可以对HTML的特殊字符进行转义,实现如下:

String.prototype.encodeHTML = function () {
    var div = document.createElement('div');  
    div.appendChild(document.createTextNode(this));  
    return div.innerHTML;
}

如果输出到页面的内容由HTML拼接完成,且内容存在用户输入的部分,则拼接过程中,对应字段需要经过HTML转义,用法如下:

function format(name){
  return '<div>' + name.encodeHTML() + '</div>';
}

脚本实现在eompBase.js中,导入该脚本的页面,都可以按照上面的写法进行转义。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,539评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,594评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,871评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,963评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,984评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,763评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,468评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,850评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,002评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,144评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,823评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,483评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,026评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,150评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,415评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,092评论 2 355

推荐阅读更多精彩内容

  • 基本准则 符合web标准,html语义化;html,css,JavaScript分离;代码简洁有序,尽可能减少冗余...
    喵呜君阅读 803评论 0 1
  • Web前端开发规范文档 规范目的: 使开发流程更加规范化。 通用规范: TAB键用两个空格代替(WINDOWS下T...
    荞叶阅读 547评论 0 1
  • 一.规范目的 使开发流程更加规范化。 二.通用规范 TAB键用两个空格代替(WINDOWS下TAB键占四个空格,L...
    overflow_hidden阅读 2,434评论 0 0
  • 我决定离开欧莎,欧莎童装。我是创业元老之一。我负责整个童装的视觉设计,天猫店铺的设计,京东店铺的设计,各个平台的设...
    花梨阅读 251评论 0 1
  • 一:丢弃错误认知 『要做到最好』的想法。这类想法过于模糊以至于没有真正提高自己行为的动机,那么对于达成目的是无用的...
    Vikax阅读 267评论 0 0