Web前端编码规范

通过分析github代码库总结出来的工程师代码书写习惯

为提高团队协作效率, 便于后台人员添加功能及前端后期优化维护, 输出高质量的作品, 特制订此文档.

本规范文档一经确认, 前端开发人员必须按本文档规范进行前台页面开发. 本文档如有不对或者不合适的地方请及时提出, 经讨论决定后可以更改此文档.

← 返回列表

目录

结构及命名规则

HTML

CSS

JavaScript

最佳原则

坚持制定好的代码规范。

无论团队人数多少,代码应该同出一门,易读易维护。

结构及命名规则

总体原则

1、全部采用小写的英文字母、数字和下划线的组合,其中不得包含汉字、空格和特殊字符。

2、指导思想:团队的每一个成员能够方便的理解每一个文件的意义。

3、第三方依赖包按原有命名和结构,无需按规范重新命名。

4、作品交付给公司其它团队后,不干涉其后续目录结构调整和命名规范。

项目目录结构

1、根目录下目录结构必须按照 业务职能进行划分,划分出的子目录,名称必须为一个单词,不宜过长。如:例子中的biz1。

2、业务目录中,如果文件太多不好管理,需要划分子目录时,也必须继续遵守根据业务逻辑划分的原则,划分子业务。如:例子中的subbiz1。

3、业务目录下可以按资源类型(js、css)划分子目录,也可以直接将资源文件放在目录下

另:较小规模的业务项目,允许不划分业务子目录,直接按第3条要求放在根目录下。

${root}表示项目的根目录

${root}/ 
    common/
    biz1/
        subbiz1/
            js/
                list.js
            css/                        
                list.css
            list.html
        subbiz2/                         
            index.js
            index.css                         
            index.html
    biz2/

目录命名原则

简洁。有习惯性缩写的单词,采用容易理解的缩写。不允许使用复数形式。如:imgs、docs是不被允许的。


img: 图片。 不允许使用image、images、imgs等。
js: javascript脚本。 不允许使用script、scripts等。
css: 样式表。 不允许使用style、styles等。 
doc: 文档目录。 不允许使用source、docs等。
lib: 引入的第三方依赖包目录。 不允许使用dep、library、dependency等。

HTML

语法

<!DOCTYPE html>
<html>
    <head>
        <title>Page title</title>
    </head>
    <body>
        <img src="images/company_logo.png" alt="Company">
        <h1 class="hello-world">Hello, world!</h1>
    </body>
</html>

head头部定义

这些规范已经在脚手架中定义好,可直接复用;


1、在页面开头使用这个简单地doctype来启用标准模式,使其在每个浏览器中尽可能一致的展现;

2、应在html标签上加上lang属性。这会给语音工具和翻译工具帮助,告诉它们应当怎么去发音和翻译。

3、通过声明一个明确的字符编码,让浏览器轻松、快速的确定适合网页内容的渲染方式,通常指定为'UTF-8'。

4、用 <meta> 标签可以指定页面应该用什么版本的IE来渲染;

5、用 <meta> 标签viewport定义移动端兼容模式;

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0,minimum-scale=1.0,maximum-scale=1.0" />
    <meta name="apple-touch-fullscreen" content="yes">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="format-detection" content="telephone=no">
    <meta name="x5-fullscreen" content="true">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
     
</head>
<body>
 ……
</body>
</html>
                    

引入CSS, JS

1、在 head 中引入页面需要的所有 CSS 资源。

解释:在页面渲染的过程中,新的CSS可能导致元素的样式重新计算和绘制,页面闪烁。

2、JavaScript 应当放在页面末尾,或采用异步加载。

解释:将 script 放在页面中间将阻断页面的渲染。出于性能方面的考虑,如非必要,请遵守此条建议。

3、如果html中css或js超过50行,必须另写css、js文件方式引入。

<!-- External CSS -->
<link rel="stylesheet" href="code_guide.css">
<!-- In-document CSS -->
<style>
                ...
</style>
<!-- External JS -->
<script src="code_guide.js"></script>
<!-- In-document JS -->
<script>
                ...
</script>

避免JS生成标签

在JS文件中生成html dom标签让内容变得更难查找,更难编辑,性能更差。应该尽量避免这种情况的出现。

属性顺序

属性应该按照特定的顺序出现以保证易读性;

class是为高可复用组件设计的,所以应处在第一位;

id更加具体且应该尽量少使用,所以将它放在第二位。

<a class="..." id="..." data-modal="toggle" href="#">Example link</a>
<input class="form-control" type="text">
<img src="..." alt="...">

减少标签数量

在编写HTML代码时,需要尽量避免多余的父节点;

很多时候,需要通过迭代和重构来使HTML变得更少。

<!-- 不好 -->
<span class="avatar">
    <img src="...">
</span>
<!-- 更好 -->
<img class="avatar" src="...">

实用高于完美

尽量遵循HTML标准和语义,但是不应该以浪费实用性作为代价;

任何时候都要用尽量小的复杂度和尽量少的标签来解决问题。

CSS

格式

需要使用缩进,交付作品前请格式化css代码。

每个属性声明末尾都要加分号。

.element {
    position: absolute;
    top: 10px;
    left: 10px;
    border-radius: 10px;
    width: 50px;
    height: 50px;
}

注释

注释统一用'/* */',具体参照右边的各种写法;

缩进与下一行代码保持一致;

可位于一个代码行的末尾,与代码间隔一个空格。

/* Modal header */
.modal-header {
    ...
}
/*
 * Modal header
 */
.modal-header {
    ...
}
.modal-header {
    /* 50px */
    width: 50px;
    color: red; /* color red */
}

引号

最外层统一使用双引号;

url的内容要用引号;

属性选择器中的属性值需要引号。

.element:after {
    content: "";
    background-image: url("logo.png");
}
li[data-type="single"] {
    ...
}

命名

/* class */
.element-content {
                ...
}
/* id */
#myDialog {
                ...
}
/* 变量 */
$colorBlack: #000;
/* 函数 */
@function pxToRem($px) {
                ...
}
/* 混合 */
@mixin centerBlock {
                ...
}
/* placeholder */
%myDialog {
                ...
}

媒体查询

尽量将媒体查询的规则靠近与他们相关的规则,不要将他们一起放到一个独立的样式文件中,或者丢在文档的最底部,这样做只会让大家以后更容易忘记他们。

.element {
                ...
}
.element-avatar{
    ...
}
@media (min-width: 480px) {
    .element {
    ...
    }
    .element-avatar {
    ...
    }
}

选择器

元素选择器用小写字母;

如无必要,不得为 id,尽量使用class

选择器的嵌套层级应不大于 4 级

选择器限定条件应尽可能精确

 /* good */
#username input {}
.comment .avatar {}
/* bad */
.page .header .login #username input {}
.comment div * {}

属性项

不允许有空的规则;

同个属性不同前缀的写法需要在垂直方向保持对齐,具体参照右边的写法;

无前缀的标准属性应该写在有前缀的属性后面;

不要在同个规则里出现重复的属性,如果重复的属性是连续的则没关系;

不要在一个文件里出现两个相同的规则;

发布的代码中不要有 @import

尽量少用'*'选择器。

/* not good */
.element {
} 
/* not good */
.element {
    border-radius: 3px;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    background: linear-gradient(to bottom, #fff 0, #eee 100%);
    background: -webkit-linear-gradient(top, #fff 0, #eee 100%);
    background: -moz-linear-gradient(top, #fff 0, #eee 100%);
} 
/* not good */
.element {
    color: rgb(0, 0, 0);
    width: 50px;
    color: rgba(0, 0, 0, .5);
}

JavaScript

格式

需要使用缩进,交付作品前请格式化js代码。

var x = 1,y = 1;
if (x < y) {
    x += 10;
} else {
    x += 1;
}

注释

单行注释双斜线后,必须跟一个空格;

建议在以下情况下加注释:

/*
 * 多行注释
 */
var x = 1;
   
if (condition) {
    // 单行注释
    allowed();
}
var zhangsan = 'zhangsan'; // one space after code
     
  

实体类

实体类(可以new的类)定义规范按示例定义

类的属性和方法都在一起,易读和理解

 //实体类的定义,首字母大写
function TextNode(value, engine) {//构造方法
    this.value = value;
    this.engine = engine;
}

//【建议】方法1,直接prototype等于对象
TextNode.prototype = {
    constructor: TextNode, //必须,需要修正constructor
    clone:function(){                         
        return this;
    },
    fun1 : function (opts) {
        ……
    }
};
//方法2:,或单个定义
TextNode.prototype.clone = function () {
    return this;
};
TextNode.prototype.fun1 = function (opts) {
    ……
};
//类的使用
var textNode = new TextNode('testvalue','testengine');
textNode.fun1();
  

静态类

静态类(无需new的,直接通过"."使用内部方法的类)定义规范按示例定义

类的属性和方法都在一起,易读和理解

//静态类的定义,首字母小写
var textNode = {
    value:null,
    engine:null,
    clone:function(){                         
        return this;
    },
    fun1 : function (opts) {
        ……
    }
};
                         
//类的使用
textNode.fun1();
  

函数

函数划分原则:尽量扁平化,嵌套不得超过3层

一个函数的代码行长度控制在 50 行以内(除var定义的文本内容外)

一个函数的参数控制在 6 个以内,建议通过 options 参数传递非数据输入型参数

不同行为或逻辑的语句集,使用空行隔开,更易阅读。

在语句的行长度超过 120 时,根据逻辑条件合理缩进。

命名

var loadingModules = {}; //变量
var $body = $('body');  //jquery对象变量
//类 
function TextNode(value, engine) {
    this.value = value;
    this.engine = engine;
}
TextNode.prototype.clone = function () {
    return this;
};
var textNode = new TextNode();
                    

分号

尽量加分号,避免潜在bug,以下几种情况后需加分号:

/* var declaration */
var x = 1;
/* expression statement */
x++;
/* do-while */
do {
    x++;
} while (x < 10);

引号

最外层统一使用单引号。

// not good
var x = "test";
// good
var y = 'foo',z = '<div id="test"></div>';

大括号

下列关键字后必须有大括号(即使代码块的内容只有一行):if, else, for, while, do, switch, try, catch, finally, with

// not good
if (condition)
    doSomething();
// good
if (condition) {
    doSomething();
}

undefined

永远不要直接使用undefined进行变量判断;

使用typeof和字符串'undefined'对变量进行判断。

// not good
if (person === undefined) {
    ...
}
// good
if (typeof person === 'undefined') {
    ...
}

数组遍历

遍历数组不使用 for in,数组对象可能存在数字以外的属性, 这种情况下 for in 不会得到正确结果。

应该在for第1个参数中定义len获取长度,第2个参数中不要出现取length值情况。

var arr = ['a', 'b', 'c'];
// 这里仅作演示, 实际中应使用 Object 类型
arr.other = 'other things';
// 正确的遍历方式
for (var i = 0, len = arr.length; i < len; i++) {
    console.log(i);
}
// 错误的遍历方式
for (var i in arr) {
    console.log(i);
}

杂项

用'===', '!==' 代替 '==', '!=';

switch、if各分支情况和一定要有注释特别说明;

不要在内层作用域的代码里声明了变量,之后却访问到了外层作用域的同名变量;

尽量避免使用 eval 函数。

尽量减少 DOM 操作;

对上下文this的引用只能使用 'that', 'self','$this'其中一个来命名;

debugger不要出现在提交的代码里;