V1.2 @Suming Lv
[TOC]目录
0.0 总体原则
0.1 核心思想
表现、内容和行为的分离。
标记应该是结构良好、语义正确 以及 普遍合法。
渐进增强,提高用户体验。
0.2 基本原则
代码一致性:
通过保持代码风格和传统的一致性,我们可以减少遗留系统维护的负担,并降低未来系统崩溃的风险。
最佳实践:
通过遵照最佳实践,我们能确保优化的页面加载、性能以及可维护的代码。
0.3 适用原则
本规范中条目如无特殊说明的,需参照执行。其中:
*为建议
**为必须
1.0 命名规则
1.1 项目命名
- 全部采用小写方式,以中划线分隔。
- 避免单字母命名。命名应具备描述性。
例:my-project-name
1.2 目录命名
参照项目命名规则;
有复数结构时,要采用复数命名法。
例:scripts, styles, images, data-models
1.3 文件命名
参照项目命名规则。
例:
HTML文件命名:error-report.html
JS文件命名:account-model.js
CSS, LESS文件命名:retina-sprites.less
1.4 HTML命名
参照项目命名规则。
1.5 JS命名
1.5.1 函数命名
- 使用小驼峰式命名对象、函数和实例。
- 使用下划线 _ 开头命名私有属性。
1) 获取单个对象的方法用 get 做前缀。
2) 获取多个对象的方法用 list 做前缀。
3) 获取统计值的方法用 count 做前缀。
4) 插入的方法用 save(推荐)或 insert 做前缀。
5) 删除的方法用 remove(推荐)或 delete 做前缀。
6) 修改的方法用 update 做前缀。
1.5.2 分页命名
1) 传参值:current(当前页,默认1)、size(分页数,默认10)
2) 响应值:total(总页数,默认0)
1.5.3 其他
说明:任何类、方法、参数、变量,严控访问范围。过宽泛的访问范围,不利于模块解耦。
1.6 CSS, LESS命名
参照项目命名规则。
2.0 HTML
2.1 语法
用四个空格来代替制表符(tab)。
嵌套元素应当缩进一次(即四个空格)。
对于属性的定义,确保全部使用双引号,而不要使用单引号。
不要在自闭合(self-closing)元素的尾部添加斜线。
IMG元素加alt注释。
为超过12行的元素块或关键逻辑添加注释,全部采用如下格式。
<!-- comment Begin -->
...
<!-- comment Begin -->
复制代码
HTML里插入JS时,前后需要增加空格
段落分隔符要使用实际对应的<p>
元素,而不是用多个<br>
标签。
在合适的条件下,充分利用<dl>
(定义列表)和<blockquote>
标签。
列表中的条目必须总是放置于<ul>
、<ol>
或<dl>
中,永远不要用一组 <div>
或<p>
来表示。
给每个表单里的字段加上<label>
标签,其中的 for 属性必须和对应的输入字段对应,这样用户就可以点击标签。同理,给标签也加上 cursor:pointer; 。
不用使用输入字段中的 size 属性。该属性是和输入字段里文本的 font-size 相关的。应该使用CSS宽度。
在某些闭合的</div>
标签旁边加上一段html注释,说明这里闭合的是什么元素。这在有大量嵌套和缩进的情况下会很有用。
不要把表格用于页面布局。
在合适的条件下,利用 microformats 和/或者 Microdata ,具体说是 hCard 和 adr。
在合适的条件下,利用<thead>
、<tbody>
和<th>
标签 (以及Scope属性)。
避免使用过时的标签,如:<b>
、<u>
、<i>
,而用<strong>
、<em>
等代替。
使用data-xxx来添加自定义数据,如:<input data-xxx="yyy"/>
。
其他字符实体请参照:字符实体
2.2 HTML5 Doctype
HTML5下默认使用:<!DOCTYPE HTML>
2.3 lang属性
html标签应加上lang属性。
2.4 meta
meta的使用需要根据具体需求按需选择,具体可参照:cool-head
Demo:
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="favicon.ico">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
复制代码
2.5 IE兼容模式
用<meta>
标签可以指定页面应该用什么版本的IE来渲染;
2.6 引入 CSS 和 JavaScript 文件
根据 HTML5 规范,在引入 CSS 和 JavaScript 文件时一般不需要指定 type 属性,因为 text/css 和 text/javascript 分别是它们的默认值。
2.7 属性顺序*
属性应该按照特定的顺序出现以保证易读性;
class
id
name
data-*
src, for, type, href, value , max-length, max, min, pattern
placeholder, title, alt
aria-*, role
required, readonly, disabled
复制代码
[//]: # class是为高可复用组件设计的,所以应处在第一位;
[//]: # id更加具体且应该尽量少使用,所以将它放在第二位。
2.8 boolean属性
boolean属性指不需要声明取值的属性,XHTML需要每个属性声明取值,但是HTML5并不需要;
<input type="text" disabled>
<input type="checkbox" value="1" checked>
<select>
<option value="1" selected>1</option>
</select>
复制代码
2.9 JS生成标签
在JS文件中生成标签让内容变得更难查找,更难编辑,性能更差。应该尽量避免这种情况的出现。
2.10 减少标签数量
在编写HTML代码时,需要尽量避免多余的父节点;
很多时候,需要通过迭代和重构来使HTML变得更少。
2.11 实用高于完美
尽量遵循HTML标准和语义,但是不应该以浪费实用性作为代价;
任何时候都要用尽量小的复杂度和尽量少的标签来解决问题。
3.0 CSS, SCSS, LESS
使用 normalize.css 让渲染效果在不同浏览器中更一致
3.1 缩进
使用4个空格。
3.2 分号
每个属性声明末尾都要加分号。
3.3 空格
以下几种情况不需要空格:
属性名后 多个规则的分隔符','前
!important '!'后
属性值中'('后和')'前
行末不要有多余的空格
以下几种情况需要空格:
属性值前 选择器'>', '+', '~'前后
'{'前
!important '!'前
@else 前后
属性值中的','后
注释'/'后和'/'前
3.4 空行
以下几种情况需要空行:
文件最后保留一个空行
'}'后最好跟一个空行,包括less中嵌套的规则
属性之间需要适当的空行,具体见属性声明顺序
3.5 换行
以下几种情况不需要换行:
'{'前
以下几种情况需要换行:
'{'后和'}'前
每个属性独占一行
多个规则的分隔符','后
3.6 注释
注释统一用'/* */'(less或scss中也不要用'//')。
缩进与下一行代码保持一致;
可位于一个代码行的末尾,与代码间隔一个空格。
3.7 引号
最外层统一使用双引号;
url的内容要用引号;
属性选择器中的属性值需要引号。
3.8 命名
类名使用小写字母,以中划线分隔
id采用驼峰式命名
less或scss中的变量、函数、混合、placeholder采用驼峰式命名
3.9 属性声明顺序*
相关的属性声明按以下顺序做分组处理,组之间需要有一个空行。
布局定位属性–>自身属性–>文本属性–>其他属性
// 例:
.declaration-order {
display: block;
float: right;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
border: 1px solid #e5e5e5;
border-radius: 3px;
width: 100px;
height: 100px;
font: normal 13px "Helvetica Neue", sans-serif;
line-height: 1.5;
text-align: center;
color: #333;
background-color: #f5f5f5;
opacity: 1;
}
// 下面是推荐的属性的顺序
[
[
"display",
"visibility",
"float",
"clear",
"overflow",
"overflow-x",
"overflow-y",
"clip",
"zoom"
],
[
"table-layout",
"empty-cells",
"caption-side",
"border-spacing",
"border-collapse",
"list-style",
"list-style-position",
"list-style-type",
"list-style-image"
],
[
"-webkit-box-orient",
"-webkit-box-direction",
"-webkit-box-decoration-break",
"-webkit-box-pack",
"-webkit-box-align",
"-webkit-box-flex"
],
[
"position",
"top",
"right",
"bottom",
"left",
"z-index"
],
[
"margin",
"margin-top",
"margin-right",
"margin-bottom",
"margin-left",
"-webkit-box-sizing",
"-moz-box-sizing",
"box-sizing",
"border",
"border-width",
"border-style",
"border-color",
"border-top",
"border-top-width",
"border-top-style",
"border-top-color",
"border-right",
"border-right-width",
"border-right-style",
"border-right-color",
"border-bottom",
"border-bottom-width",
"border-bottom-style",
"border-bottom-color",
"border-left",
"border-left-width",
"border-left-style",
"border-left-color",
"-webkit-border-radius",
"-moz-border-radius",
"border-radius",
"-webkit-border-top-left-radius",
"-moz-border-radius-topleft",
"border-top-left-radius",
"-webkit-border-top-right-radius",
"-moz-border-radius-topright",
"border-top-right-radius",
"-webkit-border-bottom-right-radius",
"-moz-border-radius-bottomright",
"border-bottom-right-radius",
"-webkit-border-bottom-left-radius",
"-moz-border-radius-bottomleft",
"border-bottom-left-radius",
"-webkit-border-image",
"-moz-border-image",
"-o-border-image",
"border-image",
"-webkit-border-image-source",
"-moz-border-image-source",
"-o-border-image-source",
"border-image-source",
"-webkit-border-image-slice",
"-moz-border-image-slice",
"-o-border-image-slice",
"border-image-slice",
"-webkit-border-image-width",
"-moz-border-image-width",
"-o-border-image-width",
"border-image-width",
"-webkit-border-image-outset",
"-moz-border-image-outset",
"-o-border-image-outset",
"border-image-outset",
"-webkit-border-image-repeat",
"-moz-border-image-repeat",
"-o-border-image-repeat",
"border-image-repeat",
"padding",
"padding-top",
"padding-right",
"padding-bottom",
"padding-left",
"width",
"min-width",
"max-width",
"height",
"min-height",
"max-height"
],
[
"font",
"font-family",
"font-size",
"font-weight",
"font-style",
"font-variant",
"font-size-adjust",
"font-stretch",
"font-effect",
"font-emphasize",
"font-emphasize-position",
"font-emphasize-style",
"font-smooth",
"line-height",
"text-align",
"-webkit-text-align-last",
"-moz-text-align-last",
"-ms-text-align-last",
"text-align-last",
"vertical-align",
"white-space",
"text-decoration",
"text-emphasis",
"text-emphasis-color",
"text-emphasis-style",
"text-emphasis-position",
"text-indent",
"-ms-text-justify",
"text-justify",
"letter-spacing",
"word-spacing",
"-ms-writing-mode",
"text-outline",
"text-transform",
"text-wrap",
"-ms-text-overflow",
"text-overflow",
"text-overflow-ellipsis",
"text-overflow-mode",
"-ms-word-wrap",
"word-wrap",
"-ms-word-break",
"word-break"
],
[
"color",
"background",
"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
"background-color",
"background-image",
"background-repeat",
"background-attachment",
"background-position",
"-ms-background-position-x",
"background-position-x",
"-ms-background-position-y",
"background-position-y",
"-webkit-background-clip",
"-moz-background-clip",
"background-clip",
"background-origin",
"-webkit-background-size",
"-moz-background-size",
"-o-background-size",
"background-size"
],
[
"outline",
"outline-width",
"outline-style",
"outline-color",
"outline-offset",
"opacity",
"filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
"-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
"-ms-interpolation-mode",
"-webkit-box-shadow",
"-moz-box-shadow",
"box-shadow",
"filter:progid:DXImageTransform.Microsoft.gradient",
"-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
"text-shadow"
],
[
"-webkit-transition",
"-moz-transition",
"-ms-transition",
"-o-transition",
"transition",
"-webkit-transition-delay",
"-moz-transition-delay",
"-ms-transition-delay",
"-o-transition-delay",
"transition-delay",
"-webkit-transition-timing-function",
"-moz-transition-timing-function",
"-ms-transition-timing-function",
"-o-transition-timing-function",
"transition-timing-function",
"-webkit-transition-duration",
"-moz-transition-duration",
"-ms-transition-duration",
"-o-transition-duration",
"transition-duration",
"-webkit-transition-property",
"-moz-transition-property",
"-ms-transition-property",
"-o-transition-property",
"transition-property",
"-webkit-transform",
"-moz-transform",
"-ms-transform",
"-o-transform",
"transform",
"-webkit-transform-origin",
"-moz-transform-origin",
"-ms-transform-origin",
"-o-transform-origin",
"transform-origin",
"-webkit-animation",
"-moz-animation",
"-ms-animation",
"-o-animation",
"animation",
"-webkit-animation-name",
"-moz-animation-name",
"-ms-animation-name",
"-o-animation-name",
"animation-name",
"-webkit-animation-duration",
"-moz-animation-duration",
"-ms-animation-duration",
"-o-animation-duration",
"animation-duration",
"-webkit-animation-play-state",
"-moz-animation-play-state",
"-ms-animation-play-state",
"-o-animation-play-state",
"animation-play-state",
"-webkit-animation-timing-function",
"-moz-animation-timing-function",
"-ms-animation-timing-function",
"-o-animation-timing-function",
"animation-timing-function",
"-webkit-animation-delay",
"-moz-animation-delay",
"-ms-animation-delay",
"-o-animation-delay",
"animation-delay",
"-webkit-animation-iteration-count",
"-moz-animation-iteration-count",
"-ms-animation-iteration-count",
"-o-animation-iteration-count",
"animation-iteration-count",
"-webkit-animation-direction",
"-moz-animation-direction",
"-ms-animation-direction",
"-o-animation-direction",
"animation-direction"
],
[
"content",
"quotes",
"counter-reset",
"counter-increment",
"resize",
"cursor",
"-webkit-user-select",
"-moz-user-select",
"-ms-user-select",
"user-select",
"nav-index",
"nav-up",
"nav-right",
"nav-down",
"nav-left",
"-moz-tab-size",
"-o-tab-size",
"tab-size",
"-webkit-hyphens",
"-moz-hyphens",
"hyphens",
"pointer-events"
]
]
复制代码
3.10 颜色
颜色16进制用小写字母;
颜色16进制尽量用简写。
3.11 属性简写
属性简写需要你非常清楚属性值的正确顺序,而且在大多数情况下并不需要设置属性简写中包含的所有值,所以建议尽量分开声明会更加清晰; margin 和 padding 相反,需要使用简写;
常见的属性简写包括:
font
background
transition
animation
3.12 媒体查询
尽量将媒体查询的规则靠近与他们相关的规则,不要将他们一起放到一个独立的样式文件中,或者丢在文档的最底部,这样做只会让大家以后更容易忘记他们。
.element {
...
}
.element-avatar{
...
}
@media (min-width: 480px) {
.element {
...
}
.element-avatar {
...
}
}
复制代码
3.13 LESS或SCSS相关
提交的代码中不要有 @debug;
声明顺序:
@extend
不包含 @content 的 @include
包含 @content 的 @include
自身属性
嵌套规则
@import 引入的文件不需要开头的'_'和结尾的'.scss';
嵌套最多不能超过5层;
@extend 中使用placeholder选择器;
去掉不必要的父级引用符号'&'。
3.14 杂项
不允许有空的规则;
元素选择器用小写字母;
去掉小数点前面的0;
去掉数字中不必要的小数点和末尾的0;
属性值'0'后面不要加单位;
同个属性不同前缀的写法需要在垂直方向保持对齐,具体参照右边的写法;
无前缀的标准属性应该写在有前缀的属性后面;
不要在同个规则里出现重复的属性,如果重复的属性是连续的则没关系;
不要在一个文件里出现两个相同的规则;
用 border: 0; 代替 border: none;;
选择器不要超过4层(在scss中如果超过4层应该考虑用嵌套的方式来写);
发布的代码中不要有 @import;
尽量少用'*'选择器。
4.0 JavaScript
4.1 缩进
- 使用4个空格
- 不要混用tab和space;
- 不要在一处使用多个tab或space;
4.2 单行长度
- 不要超过80,使用字符串连接号连接(word wrap可不考虑单行长度)。
- 程序化生成字符串时,使用模板字符串替代字符串连接。
// good
function sayHi(name){
return `How are you ${name}?`
}
复制代码
4.3 分号
每行逻辑后面需要以分号结尾
4.4 空格
以下几种情况不需要空格:
对象的属性名后
前缀一元运算符后
后缀一元运算符前
函数调用括号前
无论是函数声明还是函数表达式,'('前不要空格
数组的'['后和']'前
对象的'{'后和'}'前
运算符'('后和')'前
以下几种情况需要空格:
二元运算符前后
三元运算符'?:'前后
代码块'{'前
下列关键字前:else, while, catch, finally
下列关键字后:if, else, for, while, do, switch, case, try, catch, finally, with, return, typeof
单行注释'//'后(若单行注释和代码同行,则'//'前也需要),多行注释'*'后
对象的属性值前
for循环,分号后留有一个空格,前置条件如果有多个,逗号后留一个空格
无论是函数声明还是函数表达式,'{'前一定要有空格
函数的参数之间
// not good
var a = {
b :1
}
// good
var a = {
b: 1
}
// not good
++ x
y ++
z = x?1:2
// good
++x
y++
z = x ? 1 : 2
// not good
var a = [ 1, 2 ]
// good
var a = [1, 2]
// not good
var a = ( 1+2 )*3
// good
var a = (1 + 2) * 3
// no space before '(', one space before '{', one space between function parameters
var doSomething = function(a, b, c) {
// do something
}
// no space before '('
doSomething(item)
// not good
for(i=0;i<6;i++){
x++
}
// good
for (i = 0; i < 6; i++) {
x++
}
复制代码
4.5 空行
以下几种情况需要空行:
变量声明后(当变量声明在代码块的最后一行时,则无需空行)
注释前(当注释在代码块的第一行时,则无需空行)
代码块后(在函数调用、数组、对象中则无需空行)
文件最后保留一个空行
4.6 换行
换行的地方,行末必须有','或者运算符;
以下几种情况不需要换行:
下列关键字后:else, catch, finally
代码块'{'前
以下几种情况需要换行:
代码块'{'后和'}'前
变量赋值后
// not good
var a = {
b: 1
, c: 2
};
x = y
? 1 : 2;
// good
var a = {
b: 1,
c: 2
};
x = y ? 1 : 2;
x = y ?
1 : 2;
// no need line break with 'else', 'catch', 'finally'
if (condition) {
...
} else {
...
}
try {
...
} catch (e) {
...
} finally {
...
}
// not good
function test()
{
...
}
// good
function test() {
...
}
// not good
var a, foo = 7, b,
c, bar = 8
// good
var a,
foo = 7,
b, c, bar = 8
复制代码
4.7 单行注释
双斜线后,必须跟一个空格;
缩进与下一行代码保持一致;
可位于一个代码行的末尾,与代码间隔一个空格。
4.8 多行注释
最少三行, '*'后跟一个空格,具体参照右边的写法;
建议在以下情况下使用:
难于理解的代码段
可能存在错误的代码段
浏览器特殊的HACK代码
业务逻辑强相关的代码
/*
* one space after '*'
*/
var x = 1
复制代码
4.9 文档注释
各类标签@param, @method等请参考 JSDoc中文、usejsdoc和JSDoc Guide;
建议在以下情况下使用:
所有常量
所有函数
所有类
/**
* @func
* @desc 一个带参数的函数
* @param {string} a - 参数a
* @param {number} b=1 - 参数b默认值为1
* @param {string} c=1 - 参数c有两种支持的取值 1—表示x 2—表示xx
* @param {object} d - 参数d为一个对象
* @param {string} d.e - 参数d的e属性
* @param {string} d.f - 参数d的f属性
* @param {object[]} g - 参数g为一个对象数组
* @param {string} g.h - 参数g数组中一项的h属性
* @param {string} g.i - 参数g数组中一项的i属性
* @param {string} [j] - 参数j是一个可选参数
*/
function foo(a, b, c, d, g, j) { ... }
复制代码
4.10 引号
最外层统一使用单引号。
4.11 变量命名
标准变量采用驼峰式命名(除了对象的属性外,主要是考虑到cgi返回的数据)
'ID'在变量名中全大写
'URL'在变量名中全大写
'Android'在变量名中大写第一个字母
'iOS'在变量名中小写第一个,大写后两个字母
常量全大写,用下划线连接
构造函数,大写第一个字母
jquery对象必须以'$'开头命名
var thisIsMyName;
var goodID;
var reportURL;
var AndroidVersion;
var iOSVersion;
var MAX_COUNT = 10;
function Person(name) {
this.name = name;
}
// not good
var body = $('body');
// good
var $body = $('body');
复制代码
4.12 变量声明
- 使用函数声明代替函数表达式。
- 一个函数作用域中所有的变量声明尽量提到函数首部,用一个var或let声明,不允许出现两个连续的var或let声明。
- 使用对象属性值的简写,并把简写的属性分组。
const name = 'name';
const age = 'age';
// bad
const obj = function(){
}
// good
const obj = {
name,
age,
sex: '男',
height: '170'
}
复制代码
- 使用解构存取和使用多属性对象。因为解构能减少临时引用属性。
// bad
function getFullName(user){
const fileName = user.firstName;
const lastName = user.lastName;
return `${firstName} ${lastName}`
}
// good
function getFullName(user){
const { firstName, lastName } = user;
return `${firstName} ${lastName}`
}
// best
function getFullName({ firstName, lastName }){
return `${firstName} ${lastName}`
}
复制代码
4.13 函数
对上下文this的引用只能使用'_this', 'that', 'self'其中一个来命名;
不要给inline function命名;
参数之间用', '分隔,注意逗号后有一个空格。
直接给函数的参数指定默认值,不要使用一个变化的函数参数。
// bad
function handleThings(opts){
opts = opts || {};
}
// good
function handleThings(opts = {}){
}
复制代码
4.14 箭头函数
- 当你必须使用函数表达式(或传递一个匿名函数)时,使用箭头函数符号。
因为箭头函数创造了新的 this 执行环境,通常情况下都能满足你的需求,而且这样的写法更为简洁。
// bad
[1, 2, 3].map(function (x) {
return x * x;
})
// good
[1, 2, 3].map(x => {
return x * x;
})
复制代码
- 如果一个函数适合用一行写出并且只有一个参数,那就把花括号、圆括号和 return 都省略掉。如果不是,那就不要省略。
// good
[1, 2, 3].map(x => x * x);
// good
[1, 2, 3].map((total, x) => {
return total + x;
})
复制代码
4.15 构造函数
- 总是使用class,避免直接操作prototype。
// bad
function Queue(contents = []){
this._queue = [...contents];
}
Queue.prototype.pop = function(){
const value = this._queue[0];
this._queue.splice(0, 1);
return value;
}
// good
class Queue {
constructor(contents = []){
this._queue = [...contents];
}
pop(){
const value = this._queue[0];
this._queue.splice(0, 1);
return value;
}
}
复制代码
- 使用 extends 继承。extends 是一个内建的原型继承方法并且不会破坏 instanceof 。
// bad
const inherits = require('inherits');
function PeekableQueue(contents) {
Queue.apply(this, contents);
}
inherits(PeekableQueue, Queue);
PeekableQueue.prototype.peek = function() {
return this._queue[0];
}
// good
class PeekableQueue extends Queue {
peek() {
return this._queue[0];
}
}
复制代码
- 方法可以返回 this 来帮助链式调用。
// bad
Jedi.prototype.jump = function() {
this.jumping = true;
return true;
};
Jedi.prototype.setHeight = function(height) {
this.height = height;
};
const luke = new Jedi();
luke.jump(); // => true
luke.setHeight(20); // => undefined
// good
class Jedi {
jump() {
this.jumping = true;
return this;
}
setHeight(height) {
this.height = height;
return this;
}
}
const luke = new Jedi();
luke.jump().setHeight(20);
复制代码
4.16 数组、对象
对象属性名不需要加引号;
对象以缩进的形式书写,不要写在一行;
数组、对象最后不要有逗号。
4.17 括号
下列关键字后必须有大括号(即使代码块的内容只有一行):
if, else, for, while, do, switch, try, catch, finally, with。
4.18 null
适用场景:
初始化一个将来可能被赋值为对象的变量
与已经初始化的变量做比较
作为一个参数为对象的函数的调用传参
作为一个返回对象的函数的返回值
不适用场景:
不要用null来判断函数调用时有无传参
不要与未初始化的变量做比较
4.19 undefined
永远不要直接使用undefined进行变量判断;
使用typeof和字符串'undefined'对变量进行判断。
4.20 jshint
用'==='
, '!=='
代替'=='
, '!='
;
for-in里一定要有hasOwnProperty的判断;
不要在内置对象的原型上添加方法,如Array, Date;
不要在内层作用域的代码里声明了变量,之后却访问到了外层作用域的同名变量;
变量不要先使用后声明;
不要在一句代码中单单使用构造函数,记得将其赋值给某个变量;
不要在同个作用域下声明同名变量;
不要在一些不需要的地方加括号,例:delete(a.b);
不要使用未声明的变量(全局变量需要加到.jshintrc文件的globals属性里面);
不要声明了变量却不使用;
不要在应该做比较的地方做赋值;
debugger不要出现在提交的代码里;
数组中不要存在空元素;
不要在循环内部声明函数;
不要像这样使用构造函数,例:new function () { ... }, new Object
;
5.0 图片及第三方资源
5.1 存放目录
- 静态类资源置于项目根目录下static文件夹
- 配置类资源置于项目根目录下assets文件夹
- 第三方库类资源置于项目根目录下components文件夹
5.2 格式
图片格式仅限于gif || png || jpg;
在保证视觉效果的情况下选择最小的图片格式与图片质量, 以减少加载时间;
5.3 命名
命名全部用小写英文字母 || 数字 || _ 的组合,其中不得包含汉字 || 空格 || 特殊字符;尽量用易懂的词汇, 便于团队其他成员理解; 另, 命名分头尾两部分, 用下划线隔开, 比如ad_left01.gif || btn_submit.gif;
5.4 其他
运用css sprite技术集中小的背景图或图标, 减小页面http请求, 但注意, 请务必在对应的sprite psd源图中划参考线, 并保存至img目录下。
6.0 JS框架&UI库
Vue、React、Angular、jQuery、小程序、公众号
6.1 jquery
6.1.1 jQuery-ui库
6.1.2 jQuery Plugin
- IE对HTML5标签支持,以及浏览器特性检测:Modernizr & html5shiv
- 定制&统一 浏览器的滚动条样式:jquery-scroll & Lionbars
- hover提示效果文字:bootstrap-tooltips & tipsy
- 滚动条跟随nav效果:bootstrap-scrollspy
- 提示冒泡文字:grumble.js
- 导航栏过渡效果:lavalamp
- 移动设备的滚动效果:iscroll 4
- Mac OS Lion 风格的滚动条:Lionbars
- 弹性SlideShow:kwicks for jQuery
- 瀑布流:isotope
- 抖动效果:jQ shake
- LightBox:fancyBox
- KenDo UI:KenDo UI
- textarea自适应高度:elastic
- 提示区域 & 提示层:noty
- 浮动话题泡:jQuery grumble
- 旋转进度:jQuery Knob
6.2 Vue 注意点
- 组件命名:
- 连字符:字母全小写且必须包含一个连字符(推荐,当直接在 DOM 中使用一个组件时)
Vue.component('my-component-name', { /* ... */ });
复制代码
- 大驼峰: 注意:当使用的不是字符串模板时,camelCase (驼峰式命名) 的 props属性需要转换为相对应的 kebab-case (连字符命名)
(1)、HTML模板:
Vue.component('child', {
// 在 JavaScript 中使用 camelCase
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>'
})
(2)、字符串模板:
<!-- 在 HTML 中使用kebab-case -->
<child my-message="hello!"></child>
复制代码
6.2.1 Vue-ui库
移动端:
PC端:
- element UI (饿了么)
- iview
- ant-design-vue
- vuetify
- Zent (有赞)
6.2.2 Vue Plugin
- 自定义滚动条 happy-scroll & Vuescroll
- 虚拟滚动列表 vue-virtual-scroll-list
6.2.3 Vue
6.3 React
6.3.1 React-ui库
移动端:
- Ant Design Mobile (Alibaba)
- Bee Mobile
- Material-UI (Google 响应式)
- Onsen UI (Angular1、Angular2+、React、Vue)
PC端:
- Ant-design (Alibaba)
- Material-UI (Google 响应式)
- Semantic-UI-React
- React-Bootstrap
- React-Desktop (MacOS & windows)
6.3.2 React Plugin
6.4 Angular
6.4.1 Angular-ui库
移动端:
- Ant Design Mobile of Angular
- Ionic
- Onsen UI (Angular1、Angular2+、React、Vue)
PC端:
- Ant Design of Angular
- Angular Material
- Kendo UI for Angular
- agGrid (js、Angular1、Angular2+、React、Vue)
- PrimeNG
- Clarity
6.3.2 Angular Plugin
6.5 小程序、公众号
6.5.1 小程序、公众号ui库
-
WeUI WXSS (微信)
-
iView WeApp (微信)
-
Vant Weapp (微信)
-
mpvue (微信、vue)
-
wepy (微信)
-
MinUI (微信)
-
Wux WeApp (微信)
-
uni-app (微信、支付宝、Android、iOS、H5)
-
Taro (微信、支付宝、H5、Native)
7.0 缓存
8.0 HTTP及接口请求
9.0 性能优化
10.0 终端兼容
10.1 分辨率兼容
10.1.1 移动端兼容
-
不同的dpr下,加载不同的尺寸的图片
如果有图片服务器,通过url获取参数,然后可以控制图片质量,也可以将图片裁剪成不同的尺寸。只需上传大图(@2x),其余小图都交给图片服务器处理,我们只要负责拼接url即可。
如果没有图片服务器,准备多份不同尺寸的图片@1x@2x@3x -
不同的dpr下,1px宽的直线需要缩放0.5
//方案一:缩小0.5倍来达到0.5px的效果 border-bottom: 1px solid #ddd; -webkit-transform:scaleY(.5); -webkit-transform-origin:0 0; //方案二:添加如下的meta标签,设置viewport(scale 0.5) <meta name="viewport" content="width=640,initial-scale=0.5,maximum-scale=0.5, minimum-scale=0.5,user-scalable=no"> 复制代码