[关闭]
@stonezhou 2016-10-19T07:21:16.000000Z 字数 13399 阅读 534

编码规范

Flagwind.UI


目录

原则

不管有多少人共同参与同一项目,确保每一行代码都像同一个人编写的。

命名规则

项目名

项目名以点号分隔。(例如:Flagwind.UI)

目录名

目录名采用全小写形式,多个单词组成时,以中划线分隔,有复数结构时,采用复数命名法。允许使用缩写单词作为目录名。(例如:js、docs、less)

文件名

文件名采用全小写形式,多个单词组成时,采用中划线连接方式。(例如:account-model.js、retina-sprites.css、error-report.html)

编辑器配置

根据以下设置来配置你的编辑器,避免代码不一致的问题。

HTML 规范

基础

  1. <!DOCTYPE html>
  2. <html lang="zh-cn">
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="renderer" content="webkit" />
  6. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  7. <meta name="viewport" content="width=device-width, initial-scale=1" />
  8. <title>Untitled</title>
  9. <meta name="description" content="" />
  10. <meta name="keywords" content="" />
  11. <!-- 核心 CSS 文件 -->
  12. <link rel="stylesheet" href="css/flagwind.min.css" />
  13. <!-- HTML5 & Media Queries 兼容文件 -->
  14. <!--[if lt IE 9]>
  15. <script src="js/html5shiv.min.js"></script>
  16. <script src="js/respond.min.js"></script>
  17. <![endif]-->
  18. </head>
  19. <body>
  20. <div class="container">
  21. ...
  22. </div>
  23. <!-- 核心 JavaScript 文件 -->
  24. <script src="js/jquery.min.js"></script>
  25. <script src="js/flagwind.min.js"></script>
  26. </body>
  27. </html>

DOCTYPE

在 HTML 页面中的第一行添加一个标准声明,使其在所有浏览器中拥有一致的展现。虽然 doctype 不区分大小写,但是按照惯例,请将 doctype 大写。

  1. <!DOCTYPE html>

语言属性

根据 HTML5 规范:

强烈建议为 html 根元素指定 lang 属性,从而为文档设置正确的语言。这将有助于语音合成工具确定其所应该采用的发音,有助于翻译工具确定其翻译时所应遵守的规则等等。

这里列出了语言代码表

  1. <!DOCTYPE html>
  2. <html lang="zh-cn">
  3. </html>

字符编码

通过声明字符编码,能够确保浏览器快速判断页面内容的渲染方式。这样做的好处是,可以避免在 HTML 中使用字符实体标记(character entity),从而全部与文档编码一致(强烈推荐 utf-8 编码)。

  1. <meta charset="utf-8" />

IE 兼容模式

IE 通过特定的 <meta> 标签来确定绘制当前页面所采用的 IE 版本。除非有强烈的特殊需求,否则最好设置为 Edge 模式,从而通知 IE 采用其所支持的最新的模式。

更多信息,请阅读这篇 Stack Overflow 文章。

  1. <meta http-equiv="X-UA-Compatible" content="IE=Edge" />

引入 CSS 和 JavaScript 文件

根据 HTML5 规范,在引入 CSS 和 JavaScript 文件时一般不需要指定 type 属性,因为 text/csstext/javascript 分别是它们的默认值。

HTML5 规范链接:

  1. <!-- 引入样式表文件 -->
  2. <link href="css/flagwind.css" rel="stylesheet" />
  3. <!-- 申明内部样式表 -->
  4. <style>
  5. /* ... */
  6. </style>
  7. <!-- 引入脚本文件 -->
  8. <script src="js/jquery.js"></script>

实用高于完美

尽量遵循 HTML 标准和语义,但是不应该以浪费实用性作为代价。任何时候都要用尽量小的复杂度和尽量少的标签来解决问题。

属性顺序

HTML 属性应当按照以下给出的顺序依次排列,确保代码的易读性。

class 用于标识高度可复用组件,理论上他们应该排在第一位。id 用于标识具体组件,应当谨慎使用(例如,页面内的书签),但为了突出 id 的重要性,所以把 id 放到了第一位。

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

布尔(boolean)型属性

布尔型属性可在声明时不赋值(XHTML 规范要求为其赋值,但是 HTML5 规范不需要。),建议采用 属性值=属性名 的方式赋值。

了解更多内容,请参考 WhatWG section on boolean attributes

  1. <!-- 不写属性代表属性为false -->
  2. <input type="checkbox" />
  3. <!-- 属性值=属性名,代表属性为true -->
  4. <input type="checkbox" checked="checked" />
  5. <select>
  6. <option value="1" selected="selected">1</option>
  7. </select>

减少标签的数量

编写 HTML 代码时,尽量避免多余的父元素。很多时候,这需要迭代和重构来实现。

  1. <!-- 糟糕的实例 -->
  2. <span class="avatar">
  3. <img src="..." />
  4. </span>
  5. <!-- 好的实例 -->
  6. <img class="avatar" src="..." />

JavaScript 生成标签

通过 JavaScript 生成的标签让内容变得不易查找、编辑,性能更差。应该尽量避免这种情况的出现。

CSS 规范

基础

更多规则请参考 Wikipedia 中的 CSS语法部分

  1. /* 糟糕的实例 */
  2. .selector, .selector-secondary, .selector[type=text] {
  3. padding:15px;
  4. margin:0px 0px 15px;
  5. background-color:rgba(0, 0, 0, 0.5);
  6. box-shadow:0px 1px 2px #CCC,inset 0 1px 0 #FFFFFF
  7. }
  8. /* 好的实例 */
  9. .selector,
  10. .selector-secondary,
  11. .selector[type="text"]
  12. {
  13. padding: 15px;
  14. margin-bottom: 15px;
  15. background-color: rgba(0,0,0,.5);
  16. box-shadow: 0 1px 2px #ccc, inset 0 1px 0 #fff;
  17. }

class 命名

  1. /* 糟糕的实例 */
  2. .t { ... }
  3. .red { ... }
  4. .header { ... }
  5. /* 好的实例 */
  6. .fw { ... }
  7. .important { ... }
  8. .fw-header { ... }

选择器

扩展阅读:

  1. /* 糟糕的实例 */
  2. span { ... }
  3. .page-container #stream .stream-item .fw .fw-header .username { ... }
  4. .avatar { ... }
  5. /* 好的实例 */
  6. .avatar { ... }
  7. .fw-header .username { ... }
  8. .fw .avatar { ... }

代码组织

  1. /*
  2. * Component section heading
  3. */
  4. .element { ... }
  5. /*
  6. * Component section heading
  7. *
  8. * Sometimes you need to include optional context for the entire component.
  9. * Do that up here if it's important enough.
  10. */
  11. .element { ... }
  12. /*
  13. * Contextual sub-component or modifer
  14. */
  15. .element-heading { ... }

声明顺序

相关的属性声明应当归为一组,并按照下面的顺序排列:

  1. Positioning(定位)
  2. Box model(盒模型)
  3. Typographic(排版)
  4. Visual(外观)

由于定位(positioning)可以从正常的文档流中移除元素,并且还能覆盖盒模型(box model)相关的样式,因此排在第一位。盒模型紧跟其后,因为他决定了一个组件的尺寸和位置。

其他属性只是影响组件的内部(inside)或者是不影响前两组属性,所以他们排在后面。

关于完整的属性以及他们的顺序,请参考 Recess

  1. .declaration-order
  2. {
  3. /* 定位 */
  4. position: absolute;
  5. top: 0;
  6. right: 0;
  7. bottom: 0;
  8. left: 0;
  9. z-index: 100;
  10. /* 盒模型 */
  11. display: block;
  12. float: right;
  13. width: 100px;
  14. height: 100px;
  15. /* 排版 */
  16. font: normal 13px "Helvetica Neue", sans-serif;
  17. line-height: 1.5;
  18. color: #333;
  19. text-align: center;
  20. /* 外观 */
  21. background-color: #f5f5f5;
  22. border: 1px solid #e5e5e5;
  23. border-radius: 3px;
  24. /* 其他 */
  25. opacity: 1;
  26. }

为了方便查阅,我们将 Recess 的顺序贴了一份出来:

  1. var order =
  2. [
  3. 'position',
  4. 'top',
  5. 'right',
  6. 'bottom',
  7. 'left',
  8. 'z-index',
  9. 'display',
  10. 'float',
  11. 'width',
  12. 'height',
  13. 'max-width',
  14. 'max-height',
  15. 'min-width',
  16. 'min-height',
  17. 'padding',
  18. 'padding-top',
  19. 'padding-right',
  20. 'padding-bottom',
  21. 'padding-left',
  22. 'margin',
  23. 'margin-top',
  24. 'margin-right',
  25. 'margin-bottom',
  26. 'margin-left',
  27. 'margin-collapse',
  28. 'margin-top-collapse',
  29. 'margin-right-collapse',
  30. 'margin-bottom-collapse',
  31. 'margin-left-collapse',
  32. 'overflow',
  33. 'overflow-x',
  34. 'overflow-y',
  35. 'clip',
  36. 'clear',
  37. 'font',
  38. 'font-family',
  39. 'font-size',
  40. 'font-smoothing',
  41. 'osx-font-smoothing',
  42. 'font-style',
  43. 'font-weight',
  44. 'hyphens',
  45. 'src',
  46. 'line-height',
  47. 'letter-spacing',
  48. 'word-spacing',
  49. 'color',
  50. 'text-align',
  51. 'text-decoration',
  52. 'text-indent',
  53. 'text-overflow',
  54. 'text-rendering',
  55. 'text-size-adjust',
  56. 'text-shadow',
  57. 'text-transform',
  58. 'word-break',
  59. 'word-wrap',
  60. 'white-space',
  61. 'vertical-align',
  62. 'list-style',
  63. 'list-style-type',
  64. 'list-style-position',
  65. 'list-style-image',
  66. 'pointer-events',
  67. 'cursor',
  68. 'background',
  69. 'background-attachment',
  70. 'background-color',
  71. 'background-image',
  72. 'background-position',
  73. 'background-repeat',
  74. 'background-size',
  75. 'border',
  76. 'border-collapse',
  77. 'border-top',
  78. 'border-right',
  79. 'border-bottom',
  80. 'border-left',
  81. 'border-color',
  82. 'border-image',
  83. 'border-top-color',
  84. 'border-right-color',
  85. 'border-bottom-color',
  86. 'border-left-color',
  87. 'border-spacing',
  88. 'border-style',
  89. 'border-top-style',
  90. 'border-right-style',
  91. 'border-bottom-style',
  92. 'border-left-style',
  93. 'border-width',
  94. 'border-top-width',
  95. 'border-right-width',
  96. 'border-bottom-width',
  97. 'border-left-width',
  98. 'border-radius',
  99. 'border-top-right-radius',
  100. 'border-bottom-right-radius',
  101. 'border-bottom-left-radius',
  102. 'border-top-left-radius',
  103. 'border-radius-topright',
  104. 'border-radius-bottomright',
  105. 'border-radius-bottomleft',
  106. 'border-radius-topleft',
  107. 'content',
  108. 'quotes',
  109. 'outline',
  110. 'outline-offset',
  111. 'opacity',
  112. 'filter',
  113. 'visibility',
  114. 'size',
  115. 'zoom',
  116. 'transform',
  117. 'box-align',
  118. 'box-flex',
  119. 'box-orient',
  120. 'box-pack',
  121. 'box-shadow',
  122. 'box-sizing',
  123. 'table-layout',
  124. 'animation',
  125. 'animation-delay',
  126. 'animation-duration',
  127. 'animation-iteration-count',
  128. 'animation-name',
  129. 'animation-play-state',
  130. 'animation-timing-function',
  131. 'animation-fill-mode',
  132. 'transition',
  133. 'transition-delay',
  134. 'transition-duration',
  135. 'transition-property',
  136. 'transition-timing-function',
  137. 'background-clip',
  138. 'backface-visibility',
  139. 'resize',
  140. 'appearance',
  141. 'user-select',
  142. 'interpolation-mode',
  143. 'direction',
  144. 'marks',
  145. 'page',
  146. 'set-link-source',
  147. 'unicode-bidi',
  148. 'speak'
  149. ]

不要使用 @import

<link> 标签相比,@import 指令要慢很多,不光增加了额外的请求次数,还会导致不可预料的问题。替代办法有以下几种:

更多信息,请阅读 Steve Souders 的文章

  1. <!-- 推荐使用 link 元素 -->
  2. <link rel="stylesheet" href="layout.css">
  3. <!-- 避免使用 @import 指令 -->
  4. <style>
  5. @import url("layout.css");
  6. </style>

媒体查询(Media query)的位置

将媒体查询放在尽可能相关规则的附近。不要将他们放在文档底部或者打包放在一个单一样式文件中。如果你把他们分开了,将来只会被大家遗忘。下面给出一个典型的示例:

  1. .element { ... }
  2. .element-avatar { ... }
  3. .element-selected { ... }
  4. @media (min-width: 480px)
  5. {
  6. .element { ...}
  7. .element-avatar { ... }
  8. .element-selected { ... }
  9. }

带前缀的属性

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

  1. .selector
  2. {
  3. -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15);
  4. box-shadow: 0 1px 2px rgba(0,0,0,.15);
  5. }

单条声明的声明块

在一个声明块中只包含一条声明的情况下,为了易读性和快速编辑可以考虑移除其中的换行。所有包含多条声明的声明块应该分为多行。

这样做的关键因素是错误检测 - 例如,一个 CSS 验证程序显示你在 183 行有一个语法错误,如果是一个单条声明的行,那就是他了。在多个声明的情况下,你必须为哪里出错了费下脑子。

  1. /* 单条声明 */
  2. .span1 { width: 60px; }
  3. .span2 { width: 140px; }
  4. .span3 { width: 220px; }
  5. /* 多条声明 */
  6. .sprite
  7. {
  8. display: inline-block;
  9. width: 16px;
  10. height: 15px;
  11. background-image: url(../images/sprite.png);
  12. }

简写形式的属性声明

在需要显示地设置所有值的情况下,应当尽量限制使用简写形式的属性声明。常见的滥用简写属性声明的情况如下:

大部分情况下,我们不需要为简写形式的属性声明指定所有值。例如,HTML 的 heading 元素只需要设置上、下边距(margin)的值,因此,在必要的时候,只需覆盖这两个值就可以。过度使用简写形式的属性声明会导致代码混乱,并且会对属性值带来不必要的覆盖从而引起意外的副作用。

Mozilla Developer Network 有一篇对不熟悉属性简写及其行为的人来说很棒的关于 shorthand properties 的文章。

  1. /* 糟糕的实例 */
  2. .element
  3. {
  4. margin: 0 0 10px;
  5. background: red;
  6. background: url("image.jpg");
  7. border-radius: 3px 3px 0 0;
  8. }
  9. /* 好的实例 */
  10. .element
  11. {
  12. margin-bottom: 10px;
  13. background-color: red;
  14. background-image: url("image.jpg");
  15. border-top-left-radius: 3px;
  16. border-top-right-radius: 3px;
  17. }

LESS 和 SASS 中的嵌套

避免不必要的嵌套。可以进行嵌套,不意味着你应该这样做。只有在需要给父元素增加样式并且同时存在多个子元素时才需要考虑嵌套。

  1. /* 糟糕的实例 */
  2. .table > thead > tr > th { }
  3. .table > thead > tr > td { }
  4. /* 好的实例 */
  5. .table > thead > tr
  6. {
  7. > th { }
  8. > td { }
  9. }

注释

代码是由人编写并维护的。请确保你的代码能够自然描述、注释良好并且易于他人理解。好的代码注释能够传达上下文关系和代码目的。不要简单地重申组件或 class 名称。

对于较长的注释,务必书写完整的句子;对于一般性注解,可以书写简洁的短语。

  1. /* 糟糕的实例 */
  2. /*
  3. * Modal header
  4. */
  5. .modal-header
  6. {
  7. ...
  8. }
  9. /* 好的实例 */
  10. /*
  11. * 包含 .modal-title 和 .modal-close 的容器。
  12. */
  13. .modal-header
  14. {
  15. ...
  16. }

JavaScript 规范

基础

命名

  1. function Animal()
  2. {
  3. this._name = null;
  4. this.getName = function()
  5. {
  6. var min = 111111, //随机数最小值
  7. max = 999999; //随机数最大值
  8. if(!this._name)
  9. {
  10. return Math.floor(Math.random() * (max - min)) + min;
  11. }
  12. return this._name;
  13. };
  14. this.setName = function(name)
  15. {
  16. this._name = name;
  17. };
  18. }

空行

缩进

缩进的单位为4个空格,规则也很简单——花括号里面的东西。这就意味着函数体、循环 (do, while, for, for-in)、if、switch,以及对象字面量中的对象属性。下面的代码就是使用缩进的示例:

  1. function outer(a, b)
  2. {
  3. var c = 1,
  4. d = 2,
  5. inner;
  6. if(a > b)
  7. {
  8. inner = function()
  9. {
  10. return {
  11. r : c - d
  12. };
  13. };
  14. }
  15. else
  16. {
  17. inner = function()
  18. {
  19. return {
  20. r : c + d
  21. };
  22. };
  23. }
  24. return inner;
  25. }

空格

空格的使用同样有助于改善代码的可读性和一致性。适合使用空格的地方包括:

花括号

花括号 {} 应总被使用,即使在它们为可选的时候。虽然在 if 或者 for 中如果语句仅一条,花括号是不需要的,但是你还是应该总是使用它们,这会让代码更有持续性和易于更新。

想象下你有一个只有一条语句的 for 循环,你可以忽略花括号,而没有解析的错误。

  1. // 糟糕的实例
  2. for(var i = 0; i < 10; i++)
  3. alert(i);

但是,如果,后来,主体循环部分又增加了行代码:

  1. // 糟糕的实例
  2. for(var i = 0; i < 10; i++)
  3. alert(i);
  4. alert(i + " is " + (i % 2 ? "odd" : "even"));

第二个 alert 已经在循环之外,缩进可能欺骗了你。为了长远打算,最好总是使用花括号,即使只有一行代码:

  1. // 好的实例
  2. for(var i = 0; i < 10; i++)
  3. {
  4. alert(i);
  5. }

因此,涉及 ifforwhiledo...whiletry...catch...finally 的地方都必须使用花括号。

for 语句

  1. var name, // 属性名称
  2. person, // Person 类的实例
  3. list = [10, 12, 13, 14, 15]; // 整型数组
  4. // 普通循环实例
  5. for(var i = 0, length = list.length; i < length; i++)
  6. {
  7. console.log(list[i]);
  8. }
  9. // for in 循环实例
  10. for(name in person)
  11. {
  12. // 判断 person 对象是否拥有指定的属性。
  13. if(person.hasOwnProperty(name))
  14. {
  15. console.log("Property name is " + name);
  16. console.log("Property value is " + person[name]);
  17. }
  18. }

switch 语句

case 需要缩进,在 break 与之后的 case 中间需要一个换行。

  1. switch(condition)
  2. {
  3. case "first":
  4. // code
  5. break;
  6. case "third":
  7. // code
  8. break;
  9. default:
  10. // code
  11. }

null 关键字

使用场景

非使用场景

undefined 关键字

  1. var person;
  2. // 糟糕的实例
  3. if(person === undefined)
  4. {
  5. ...
  6. }
  7. // 好的实例
  8. if(typeof person === "undefined")
  9. {
  10. ...
  11. }

注释

单行注释

  1. // 好的实例
  2. if(condition)
  3. {
  4. // 条件成立,执行 allowed 函数。
  5. allowed();
  6. }
  7. var name = "jason"; // 双斜线距离分号一个缩进,双斜线后始终保留一个空格。

多行注释

什么时候使用多行注释?

多行注释的标准?

  1. /*
  2. * 注释内容与星标前保留一个空格
  3. */

文档注释

请按照如下场景添加文档注释,具体用到的标签(例如:@param)请参考 JSDoc

  1. /*!
  2. * Flagwind.UI(Alert) v1.0.1
  3. * Copyright 2014 Flagwind Inc. All rights reserved.
  4. * Licensed under the MIT License.
  5. * https://github.com/Flagwind/Flagwind.UI/blob/master/LICENSE
  6. *
  7. * @author jason
  8. * @email jasonsoop@gmail.com
  9. !*/
  10. +function($)
  11. {
  12. "use strict";
  13. /**
  14. * @public @class 初始化 Alert 类的新实例。
  15. * @param {object=} options 配置选项。
  16. * @return {object} this
  17. */
  18. var Alert = function(options)
  19. {
  20. return this;
  21. }
  22. /**
  23. * @public @property {string} 版本号
  24. */
  25. Alert.VERSION = "1.0.1";
  26. /**
  27. * @public 显示提示框。
  28. * @param {(string|number)} duration 一个字符串或数字用于控制动画的时长。
  29. * @return {object} this
  30. */
  31. Alert.prototype.show = function(duration)
  32. {
  33. return this;
  34. }
  35. }(jQuery);
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注