WEB前端开发规范

1. 基本原则

1.1 结构、样式、行为分离

尽量确保文档和模板只包含 HTML 结构,样式都放到样式表里,行为都放到脚本里。

1.2 缩进

统一两个空格缩进(总之缩进统一即可),不要使用 Tab 或者 Tab、空格混搭。

1.3 文件编码

使用不带 BOM 的 UTF-8 编码。

  • 在 HTML中指定编码 <meta charset="utf-8">
  • 无需使用 @charset 指定样式表的编码,它默认为 UTF-8
1.4 一律使用小写字母
<!-- Recommended -->
<img src="google.png" alt="Google">

<!-- Not recommended -->
<A HREF="/">Home</A>
/* Recommended */
color: #e5e5e5;

/* Not recommended */
color: #E5E5E5;
1.5 省略外链资源 URL 协议部分

省略外链资源(图片及其它媒体资源)URL 中的 http / https 协议,使 URL 成为相对地址,避免 Mixed Content 问题,减小文件字节数。

1.5.1 其它协议(ftp 等)的 URL 不省略。

<!-- Recommended -->
<script src="//www.google.com/js/gweb/analytics/autotrack.js"></script>

<!-- Not recommended -->
<script src="http://www.google.com/js/gweb/analytics/autotrack.js"></script>
/* Recommended */
.example {
  background: url(//www.google.com/images/example);
}

/* Not recommended */
.example {
  background: url(http://www.google.com/images/example);
}
1.6 统一注释

通过配置编辑器,可以提供快捷键来输出一致认可的注释模式。

1.6.1 HTML 注释
  • 模块注释

    <!-- 文章列表列表模块 -->
    <div class="article-list">
    ...
    </div>
    
  • 区块注释

    <!--
    @name: Drop Down Menu
    @description: Style of top bar drop down menu.
    @author: Ashu(Aaaaaashu@gmail.com)
    -->
    
1.6.2 CSS 注释

组件块和子组件块以及声明块之间使用一空行分隔,子组件块之间三空行分隔;

/* ==========================================================================
   组件块
 ============================================================================ */

/* 子组件块
 ============================================================================ */
.selector {
  padding: 15px;
  margin-bottom: 15px;
}



/* 子组件块
 ============================================================================ */
.selector-secondary {
  display: block; /* 注释*/
}

.selector-three {
  display: span;
}
1.6.3 JavaScript 注释
  • 单行注释

必须独占一行。// 后跟一个空格,缩进与下一行被注释说明的代码一致。

  • 多行注释

避免使用 /*...*/ 这样的多行注释。有多行注释内容时,使用多个单行注释。

  • 函数/方法注释
  • 函数/方法注释必须包含函数说明,有参数和返回值时必须使用注释标识。;
  • 参数和返回值注释必须包含类型信息和说明;
  • 当函数是内部函数,外部不可访问时,可以使用 @inner 标识;
/**
 * 函数描述
 *
 * @param {string} p1 参数1的说明
 * @param {string} p2 参数2的说明,比较长
 *     那就换行了.
 * @param {number=} p3 参数3的说明(可选)
 * @return {Object} 返回值描述
 */
function foo(p1, p2, p3) {
    var p3 = p3 || 10;
    return {
        p1: p1,
        p2: p2,
        p3: p3
    };
}
  • 文件注释

文件注释用于告诉不熟悉这段代码的读者这个文件中包含哪些东西。 应该提供文件的大体内容, 它的作者, 依赖关系和兼容性信息。如下:

/**
 * @fileoverview Description of file, its uses and information
 * about its dependencies.
 * @author user@meizu.com (Firstname Lastname)
 * Copyright 2015 Meizu Inc. All Rights Reserved.
 */
1.7 代码验证


2. HTML

2.1 通用约定
2.1.1 标签
  • 自闭合(self-closing)标签,无需闭合 ( 例如: img input br hr 等 );
  • 可选的闭合标签(closing tag),需闭合 ( 例如:</li></body> );
  • 尽量减少标签数量;
<img src="images/google.png" alt="Google">
<input type="text" name="title">

<ul>
  <li>Style</li>
  <li>Guide</li>
</ul>

<!-- Not recommended -->
<span class="avatar">
  <img src="...">
</span>

<!-- Recommended -->
<img class="avatar" src="...">
2.1.2 Class 与 ID
  • class 应以功能或内容命名,不以表现形式命名;
  • class 与 id 单词字母小写,多个单词组成时,采用中划线-分隔;
  • 使用唯一的 id 作为 Javascript hook, 同时避免创建无样式信息的 class;
<!-- Not recommended -->
<div class="j-hook left contentWrapper"></div>

<!-- Recommended -->
<div id="j-hook" class="sidebar content-wrapper"></div>
2.1.3 属性顺序

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

  • id
  • class
  • name
  • data-xxx
  • src, for, type, href
  • title, alt
  • aria-xxx, role
<a id="..." class="..." data-modal="toggle" href="###"></a>

<input class="form-control" type="text">

<img src="..." alt="...">
2.1.4 引号

属性的定义,统一使用双引号。

<!-- Not recommended -->
<span id='j-hook' class=text>Google</span>

<!-- Recommended -->
<span id="j-hook" class="text">Google</span>
2.1.5 嵌套

a 不允许嵌套 div这种约束属于语义嵌套约束,与之区别的约束还有严格嵌套约束,比如a 不允许嵌套 a

严格嵌套约束在所有的浏览器下都不被允许;而语义嵌套约束,浏览器大多会容错处理,生成的文档树可能相互不太一样。

(1) 语义嵌套约束

  • <li> 用于 <ul><ol> 下;
  • <dd>, <dt> 用于 <dl> 下;
  • <thead>, <tbody>, <tfoot>, <tr>, <td> 用于 <table> 下;

(2) 严格嵌套约束

  • inline-Level 元素,仅可以包含文本或其它 inline-Level 元素;
  • <a>里不可以嵌套交互式元素<a><button><select>等;
  • <p>里不可以嵌套块级元素<div><h1>~<h4><p><ul>/<ol>/<li><dl>/<dt>/<dd><form>等。
2.1.6 布尔值属性

HTML5 规范中 disabledcheckedselected 等属性不用设置值。

<input type="text" disabled>

<input type="checkbox" value="1" checked>

<select>
  <option value="1" selected>1</option>
</select>


2.2 HEAD

2.2.1 文档类型

为每个 HTML 页面的第一行添加标准模式(standard mode)的声明, 这样能够确保在每个浏览器中拥有一致的表现。

<!DOCTYPE html>
2.2.2 字符编码
  • 以无 BOM 的 utf-8 编码作为文件格式;
  • 指定字符编码的 meta 必须是 head 的第一个直接子元素;
<html>
  <head>
    <meta charset="utf-8">
    ......
  </head>
  <body>
    ......
  </body>
</html>
2.2.3 IE 兼容模式

优先使用最新版本的IE 和 Chrome 内核

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
2.2.4 SEO 优化
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <!-- SEO -->
    <title>Style Guide</title>
    <meta name="keywords" content="your keywords">
    <meta name="description" content="your description">
    <meta name="author" content="author,email address">
</head>
2.2.5 favicon

在未指定 favicon 时,大多数浏览器会请求 Web Server 根目录下的 favicon.ico 。为了保证 favicon 可访问,避免404,必须遵循以下两种方法之一:

  • 在 Web Server 根目录放置 favicon.ico 文件;
  • 使用 link 指定 favicon;
<link rel="shortcut icon" href="path/to/favicon.ico">


3. css

3.1 css属性顺序
  • 显示属性;
  • 元素位置;
  • 元素属性;
  • 元素内容属性;
  • css书写顺序:

    :::html
    例子:
    .header {
     /* 显示属性 */
     display || visibility
     list-style
     position
     top || right || bottom || left
     z-index
     clear
     float
    
     /* 自身属性 */
     width
     max-width || min-width
     height
     max-height || min-height
     overflow || clip
     margin 
     padding
     outline
     border
     background
    
     /* 文本属性 */
     color
     font
     text-overflow
     text-align
     text-indent
     line-height
     white-space
     vertical-align
     cursor
     content
    }
3.2 css写法
  • 小图片(必须)sprite 合并
  • 每个样式属性后加 “;”
  • 禁止将样式写为单行


    .hotel-content {margin: 10px; background-color: #efefef;}

  • 禁止使用行内(inline)样式

  • 禁止使用”*”来选择元素

    /*别这样写*/
    * {
    margin: 0;
    padding: 0;
    }

  • 带前缀的属性
    当使用特定浏览器带有前缀的属性时,通过缩进的方式,让每个属性的值在垂直方向对齐,这样便于多行编辑。如:

    .selector {
      -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15);
           box-shadow: 0 1px 2px rgba(0,0,0,.15);
    }
  • 优化css选择器
    css选择器是从右边到左边进行匹配的。如:

    #header a {
     color: #444;
    }


4. JavaScript

4.1 通用约定
4.1.1注释

(1) 原则

  • As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性、可读性。
  • As long as necessary(如有必要,尽量详尽):合理的注释、空行排版等,可以让代码更易阅读、更具美感。

(2) 单行注释

必须独占一行。// 后跟一个空格,缩进与下一行被注释说明的代码一致。

(3) 多行注释

避免使用 /*...*/ 这样的多行注释。有多行注释内容时,使用多个单行注释。

(4) 函数/方法注释

  1. 函数/方法注释必须包含函数说明,有参数和返回值时必须使用注释标识。;
  2. 参数和返回值注释必须包含类型信息和说明;
  3. 当函数是内部函数,外部不可访问时,可以使用 @inner 标识;
/**
 * 函数描述
 *
 * @param {string} p1 参数1的说明
 * @param {string} p2 参数2的说明,比较长
 *     那就换行了.
 * @param {number=} p3 参数3的说明(可选)
 * @return {Object} 返回值描述
 */
function foo(p1, p2, p3) {
    var p3 = p3 || 10;
    return {
        p1: p1,
        p2: p2,
        p3: p3
    };
}

(5) 文件注释

文件注释用于告诉不熟悉这段代码的读者这个文件中包含哪些东西。 应该提供文件的大体内容, 它的作者, 依赖关系和兼容性信息。如下:

/**
 * @fileoverview Description of file, its uses and information
 * about its dependencies.
 * @author user@meizu.com (Firstname Lastname)
 * Copyright 2009 Meizu Inc. All Rights Reserved.
 */
4.1.2 命名

(1) 变量, 使用 Camel 命名法。

var loadingModules = {};

(2) 私有属性、变量和方法以下划线 _ 开头。

var _privateMethod = {};

(3) 常量, 使用全部字母大写,单词间下划线分隔的命名方式。

var HTML_ENTITY = {};
  • 函数, 使用 Camel 命名法。
  • 函数的参数, 使用 Camel 命名法。
function stringFormat(source) {}

function hear(theBells) {}
  • , 使用 Pascal 命名法
  • 类的 方法 / 属性, 使用 Camel 命名法
function TextNode(value, engine) {
    this.value = value;
    this.engine = engine;
}

TextNode.prototype.clone = function () {
    return this;
};
  • 枚举变量 使用 Pascal 命名法。
  • 枚举的属性, 使用全部字母大写,单词间下划线分隔的命名方式。
var TargetState = {
    READING: 1,
    READED: 2,
    APPLIED: 3,
    READY: 4
};

由多个单词组成的 缩写词,在命名中,根据当前命名法和出现的位置,所有字母的大小写与首字母的大小写保持一致。

function XMLParser() {}

function insertHTML(element, html) {}

var httpRequest = new HTTPRequest();
4.1.3 命名语法

类名,使用名词。

function Engine(options) {}

函数名,使用动宾短语。

function getStyle(element) {}

boolean 类型的变量使用 is 或 has 开头。

var isReady = false;
var hasMoreCommands = false;

Promise 对象用动宾短语的进行时表达。

var loadingData = ajax.get('url');
loadingData.then(callback);
4.1.4 接口命名规范
  1. 可读性强,见名晓义;
  2. 尽量不与 jQuery 社区已有的习惯冲突;
  3. 尽量写全。不用缩写,除非是下面列表中约定的;(变量以表达清楚为目标,uglify 会完成压缩体积工作)
(1) True 和 False 布尔表达式

类型检测优先使用 typeof。对象类型检测使用 instanceof。null 或 undefined 的检测使用 == null。

下面的布尔表达式都返回 false:

  • null
  • undefined
  • ” 空字符串
  • 0 数字0

但下面的, 都返回 true:

  • ‘0’ 字符串0
  • [] 空数组
  • {} 空对象
(2) 不要在 Array 上使用 for-in 循环

for-in 循环只用于 object/map/hash 的遍历, 对 Array 用 for-in 循环有时会出错. 因为它并不是从 0 到 length - 1 进行遍历, 而是所有出现在对象及其原型链的键值。

// Not recommended
function printArray(arr) {
  for (var key in arr) {
    print(arr[key]);
  }
}

printArray([0,1,2,3]);  // This works.

var a = new Array(10);
printArray(a);  // This is wrong.

a = document.getElementsByTagName('*');
printArray(a);  // This is wrong.

a = [0,1,2,3];
a.buhu = 'wine';
printArray(a);  // This is wrong again.

a = new Array;
a[3] = 3;
printArray(a);  // This is wrong again.

// Recommended
function printArray(arr) {
  var l = arr.length;
  for (var i = 0; i < l; i++) {
    print(arr[i]);
  }
}
(3) 二元和三元操作符

操作符始终写在前一行, 以免分号的隐式插入产生预想不到的问题。

var x = a ? b : c;

var y = a ?
    longButSimpleOperandB : longButSimpleOperandC;

var z = a ?
        moreComplicatedB :
        moreComplicatedC;

. 操作符也是如此:

var x = foo.bar().
    doSomething().
    doSomethingElse();
(4) 条件(三元)操作符 (?:)

三元操作符用于替代 if 条件判断语句。

// Not recommended
if (val != 0) {
  return foo();
} else {
  return bar();
}

// Recommended
return val ? foo() : bar();
(5) && 和 ||

二元布尔操作符是可短路的, 只有在必要时才会计算到最后一项。

// Not recommended
function foo(opt_win) {
  var win;
  if (opt_win) {
    win = opt_win;
  } else {
    win = window;
  }
  // ...
}

if (node) {
  if (node.kids) {
    if (node.kids[index]) {
      foo(node.kids[index]);
    }
  }
}

// Recommended
function foo(opt_win) {
  var win = opt_win || window;
  // ...
}

var kid = node && node.kids && node.kids[index];
if (kid) {
  foo(kid);
}


4.2 jQuery 规范

4.2.1 使用最新版本的 jQuery

最新版本的 jQuery 会改进性能和增加新功能,若不是为了兼容旧浏览器,建议使用最新版本的 jQuery。以下是三条常见的 jQuery 语句,版本越新,性能越好:

$('.elem')
$('.elem', context)
context.find('.elem')

分别使用 1.4.2、1.4.4、1.6.2 三个版本测试浏览器在一秒内能够执行多少次,结果 1.6.2 版执行次数远超两个老版本。

4.2.2 jQuery 变量
  1. 存放 jQuery 对象的变量以 $ 开头;
  2. 将 jQuery 选择器返回的对象缓存到本地变量中复用;
  3. 使用驼峰命名变量;
var $myDiv = $("#myDiv");
$myDiv.click(function(){...});
4.2.3 选择器
  1. 尽可能的使用 ID 选择器,因为它会调用浏览器原生方法 document.getElementById 查找元素。当然直接使用原生 document.getElementById 方法性能会更好;
  2. 在父元素中选择子元素使用 .find() 方法, 因为 ID 选择器没有使用到 Sizzle 选择器引擎来查找元素;
// Not recommended
var $productIds = $("#products .class");

// Recommended
var $productIds = $("#products").find(".class");
4.2.4 DOM 操作
  1. 当要操作 DOM 元素的时候,尽量将其分离节点,操作结束后,再插入节点;
  2. 使用字符串连接或 array.join 要比 .append()性能更好;
var $myList = $("#list-container > ul").detach();
//...a lot of complicated things on $myList
$myList.appendTo("#list-container");
// Not recommended
var $myList = $("#list");
for(var i = 0; i < 10000; i++){
    $myList.append("<li>"+i+"</li>");
}

// Recommended
var $myList = $("#list");
var list = "";
for(var i = 0; i < 10000; i++){
    list += "<li>"+i+"</li>";
}
$myList.html(list);

// Much to recommended
var array = [];
for(var i = 0; i < 10000; i++){
    array[i] = "<li>"+i+"</li>";
}
$myList.html(array.join(''));
4.2.5 事件
  • 如果需要,对事件使用自定义的 namespace,这样容易解绑特定的事件,而不会影响到此 DOM 元素的其他事件监听;
  • 对 Ajax 加载的 DOM 元素绑定事件时尽量使用事件委托。事件委托允许在父元素绑定事件,子代元素可以响应事件,也包括 Ajax 加载后添加的子代元素;
$("#myLink").on("click.mySpecialClick", myEventHandler);
$("#myLink").unbind("click.mySpecialClick");
// Not recommended
$("#list a").on("click", myClickHandler);

// Recommended
$("#list").on("click", "a", myClickHandler);
4.2.6 链式写法
  • 尽量使用链式写法而不是用变量缓存或者多次调用选择器方法;
  • 当链式写法超过三次或者因为事件绑定变得复杂后,使用换行和缩进保持代码可读性;
$("#myDiv").addClass("error").show();
$("#myLink")
  .addClass("bold")
  .on("click", myClickHandler)
  .on("mouseover", myMouseOverHandler)
  .show();
4.2.7 其他


  • 多个参数使用对象字面量存储;
  • 不要将 CSS 写在 jQuery 里面;
  • 正则表达式仅准用 .test() 和 .exec() 。不准用 “string”.match() ;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值