一虐块、What.
本文的“html、css和js的基本開發(fā)規(guī)范”所指的是什么渗钉?
首先,它不涉及太深層的性能優(yōu)化。其次澜搅,它指的只是個人所認(rèn)為的前端開發(fā)規(guī)范化和專業(yè)化路上的第一步,主要分為HTML開發(fā)規(guī)范邪锌、CSS開發(fā)規(guī)范和Javascript開發(fā)規(guī)范三個模塊勉躺。
二、Why.
為什么學(xué)習(xí)前段基本的開發(fā)規(guī)范觅丰?
我認(rèn)為開發(fā)的規(guī)范就像做人的原則一樣饵溅,一個人走向成熟的標(biāo)志之一就是在為人處世的原則上的體現(xiàn)。前端開發(fā)人員剛?cè)腴T時妇萄,幾乎都沒有自己的開發(fā)規(guī)范蜕企。當(dāng)你基本能開發(fā)出一般頁面、達(dá)到入門級水平后冠句,可能你覺得自己的代碼很亂轻掩、容錯性和可維護(hù)性都很差,那么此時是你學(xué)習(xí)前端開發(fā)規(guī)范的最佳時刻了懦底。
三唇牧、How.
怎樣建立基本的前端開發(fā)規(guī)范?我認(rèn)為可以從如下幾個方面著手聚唐。
(一)HTML規(guī)范.
- 頁面的第一行添加標(biāo)準(zhǔn)模式聲明 <!DOCTYPE html>
- 代碼縮進(jìn):tab鍵設(shè)置四個空格(通常在軟件右下角設(shè)置相應(yīng)空格大小奋构,有些IDE已自動設(shè)置好。)
- html中除了開頭的DOC和 'UTF-8'或者h(yuǎn)ead里特殊情況可以大寫外拱层,其他都為小寫弥臼,css類都為小寫。
- 為 html 根元素指定 lang 屬性根灯,用來定義當(dāng)前文檔顯示的語言類型径缅,例如 lang="zh-CN"、lang="en"烙肺,利于搜索引擎纳猪、屏幕閱讀器等對頁面的語言類型準(zhǔn)確識別。
- 設(shè)置針對IE8瀏覽器的兼容設(shè)置桃笙, <meta http-equiv="X-UA-Compatible" content="IE=Edge">(用來指定IE8瀏覽器去模擬某個特定版本的IE瀏覽器的渲染方式)氏堤; <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />添加”chrome=1“將允許站點在使用了谷歌瀏覽器內(nèi)嵌框架(Chrome Frame)的客戶端渲染,對于沒有使用的搏明,則沒有任何影響鼠锈。
- 引入css文件使用<link>標(biāo)簽而不用@import(指令慢闪檬,@import多用于css文件內(nèi)引入。)
- 在HTML5規(guī)范下购笆,在引入CSS和JS時不需要指明 type(text/css 和 text/javascript 分別是他們的默認(rèn)值)
- 注釋全局統(tǒng)一("<! -- 注釋內(nèi)容--!>" --后不要留空格粗悯,若留空格,其他注釋全加空格同欠,方便后續(xù)程序開發(fā))
- 命名規(guī)范:class用 “-” 样傍;ID用 “_” ;name:data-自定義名铺遂;
根據(jù)內(nèi)容書寫語義化編碼:可用以項目名簡寫開頭-語義化名稱衫哥;
class="tb-head"; id="tb_head"; data-head="tb-head";
- 屬性排序(方便整理代碼):
1、根據(jù)屬性定義排序 : class,id,name排序 (建議用此方法)
(class用于標(biāo)識高度可復(fù)用組件襟锐,因此排首位撤逢,id用于標(biāo)識具體組件,慎用捌斧,因此排第二位);
2、特殊屬性可根據(jù)元素跟隨排序泉沾,后根據(jù)(1)方法排序;
3捞蚂、根據(jù)字母開頭順序排序;
<a class="..." id="..." data-modal="toggle" href="#">
Example link
</a>
- 減少標(biāo)簽數(shù)量(DOM元素)
- 在HTML5規(guī)范下,布爾型屬性可以在聲明時不賦值
<input type="checkbox" value="1" checked>
(二)CSS規(guī)范.
- 縮進(jìn):使用 4 個空格做為一個縮進(jìn)層級跷究,不允許使用 2 個空格 或 tab 字符姓迅。
- 添加空格(投入生產(chǎn)前,可以通過某些工具壓縮css文件俊马,去掉空格):
1丁存、每個聲明塊的左花括號前添加一個空格;
2柴我、每條聲明語句的" : "后應(yīng)該插一個空格解寝;
3、屬性多值每個逗號后應(yīng)該插入空格 eg:box-shadow,border-image艘儒;
4聋伦、不要在rgb()、rgba()界睁、hsl()觉增、hsla() 或 rect() 值的內(nèi)部的逗號后面插入空格;
5翻斟、對于屬性值或顏色參數(shù)逾礁,省略小于 1 的小數(shù)前面的 0 (例如,.5 代替 0.5访惜;-.5px 代,替 -0.5px)
6嘹履、 >腻扇、+、~ 選擇器的兩邊各保留一個空格植捎。
.content > .content-header > .title {
font-size: 2em;
}
- 選擇器規(guī)范
1衙解、當(dāng)構(gòu)建選擇器時應(yīng)該使用清晰,準(zhǔn)確和有語義的 class 名焰枢。盡量減少使用標(biāo)簽選擇器蚓峦;
不推薦:
div.content > header.content-header > h2.title {
font-size: 2em;
}
推薦:
.content > .content-header > .title {
font-size: 2em;
}
2、使用提供的簡寫屬性(font济锄、background等等)
3暑椰、為選擇器中的屬性添加雙引號 不允許單引號
例如,input[type="text"]荐绝。只有在某些情況下是可選的一汽,但是,為了代碼的一致性低滩,建議都加上雙引號召夹。
4、選擇器的嵌套層級應(yīng)不大于 3 級恕沫,位置靠后的限定條件應(yīng)盡可能精確监憎,避免使用不必要的嵌套,只有在必須將樣式限制在父元素內(nèi)(也就是后代選擇器)婶溯,并且存在多個需要嵌套的元素時才使用嵌套鲸阔。
// Without nesting
.table > thead > tr > th { … }
.table > thead > tr > td { … }
// With nesting
.table > thead > tr {
> th { … }
> td { … }
}
5、為選擇器分組時迄委,將單獨(dú)的選擇器單獨(dú)存放在一行 褐筛。
.selector,
.selector-second,
.selector[type="text"] {
padding: 15px;
margin-bottom: 15px;
background-color: rgba(0, 0, 0, 0.5);
box-shadow: 0 1px 2px #ccc, inset 0 1px 0 #fff;
}
- 簡寫:十六進(jìn)制值應(yīng)該全部小寫,盡可能簡寫 eg:#fff;.避免為 0 值指定單位叙身;例如渔扎,用 margin: 0; 代替 margin: 0px;
同時,應(yīng)當(dāng)盡量限制使用簡寫形式的屬性聲明信轿,過度使用簡寫形式的屬性聲明會導(dǎo)致代碼混亂赞警,并且會對屬性值帶來不必要的覆蓋從而引起意外的副作用。常見的濫用簡寫屬性聲明如下幾個:
margin: 0 0 10px;可以用margin-bottom: 10px;
background: red;可以用 background-color: red;
background: url("image.jpg");可以用background-image: url("image.jpg"); - 行規(guī)范:
1虏两、每行不得超過 120 個字符愧旦,除非單行不可分割。
2定罢、聲明塊右花括號應(yīng)當(dāng)成行笤虫。
3、對于超長的樣式,在樣式值的 空格 處或 , 后換行琼蚯,建議按邏輯分組酬凳。 - 聲明順序:
1、. 相關(guān)的屬性聲明應(yīng)當(dāng)歸為一組遭庶,并按照下面的順序排列:
Positioning宁仔、Box model、Typographic峦睡、Visual
由于定位(positioning)可以從正常的文檔流中移除元素翎苫,并且還能覆蓋盒模型(box model)相關(guān)的樣式,因此排在首位榨了。盒模型排在第二位煎谍,因為它決定了組件的尺寸和位置。其他屬性只是影響組件的內(nèi)部(inside)或者是不影響前兩組屬性龙屉,因此排在后面呐粘。
.declaration-order {
/* Positioning */
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
/* Box-model */ display: block;
float: right;
width: 100px;
height: 100px;
/* Typography */
font: normal 13px "Helvetica Neue", sans-serif;
line-height: 1.5;
color: #333;
text-align: center;
/* Visual */
background-color: #f5f5f5;
border: 1px solid #e5e5e5;
border-radius: 3px;
/* Misc */
opacity: 1;
}
- 帶前綴的屬性:當(dāng)使用特定廠商的帶有前綴的屬性時,通過縮進(jìn)的方式转捕,讓每個屬性的值在垂直方向?qū)R作岖,這樣便于多行編輯。
-webit-box-show: 0 1px 2px rgba(0,0,0,.15);
box-show: 0 1px 2px rgba(0,0,0,.15);
(三)Javascript規(guī)范
- 命名:
1五芝、變量命名:
變量命名使用有意義的單詞和駝峰式命名痘儡。
臨時變量簡寫:str,num,bol,fun,arr。
循環(huán)變量簡寫:i , j , k与柑。
全局變量使用g作為前綴谤辜,如gUserName , gLoginTime蓄坏。
常量全部字母都大寫价捧,如: PI , COPYRIGHT。注:常量可存在于函數(shù)中涡戳,也可存在于全局结蟋。
2、函數(shù)(方法)命名:
統(tǒng)一使用動詞或動詞加名詞的形式渔彰。如getVersion() , submitForm()嵌屎。
涉及返回邏輯值的函數(shù)可以使用is , has 等表示邏輯的詞語代替動詞。 內(nèi)部函數(shù)前加上 ‘‘前綴恍涂。
可選參數(shù)以 ‘opt’ 開頭.
3宝惰、類(對象)命名:
類名首字母大寫。
屬性名為具有一定意義的名詞再沧。私有屬性加 ““尼夺。
方法名為有意義的動詞[+名詞],首字母小寫。私有方法加 ‘_”淤堵。 - 命名空間:為避免全局命名的沖突,在全局作用域上使用一個與項目或文件相關(guān)的名字來劃分作用域空間.(類似于java中的封裝)寝衫。
var calcultor = {};
calcultor.add = function() {
...
};
calcultor.sub = function() {
...
};
- 傳遞的類型:
原始值:按值傳遞 string/number/boolean/null/undefined 注:null和undefine是不同的.
復(fù)雜類型:按引用傳遞 object/array/function. - 對象規(guī)范:
1、使用字面值創(chuàng)建對象拐邪。
/*bad*/
var item = new Object();
/*good*/
var item = {};
2慰毅、不要使用保留字作為鍵。
/*bad*/
var superman = {
class:'superhero',
default:{ clark:'kent' },
private: true
}
/*good*/
var superman = {
klass: 'superhero',
defaults:{ clark: 'kent' },
hidden: true
};
3扎阶、 當(dāng)使用變量訪問對象中的屬性時使用中括號(俗稱方括號)汹胃。
var luke = {
jedi: true,
age: 28
};
function getProp(prop){
return luke[prop];
}
var isJedi = getProp('jedi');
- 數(shù)組規(guī)范:
1、使用字面量創(chuàng)建數(shù)組乘陪。
/*bad*/
var items = new Array();
/*good*/
var items = [];
2统台、數(shù)組長度不知時,使用push添加元素啡邑。
var someStack = [];
/*bad*/
someStack[someStack.length] = 'abcdefg';
/*good*/
someStack.push('abcdefg');
3贱勃、使用slice()方法拷貝數(shù)組。
var len = items.length,
itemsCopy = [],
i;
/*bad*/
for(i = 0; i < len; i++){
itemsCopy[i] = items[i];
}
/*good*/
itemsCopy = items.slice();
- 函數(shù)規(guī)范:
1谤逼、不要在一個非函數(shù)塊里面聲明一個函數(shù)贵扰,應(yīng)該把那個函數(shù)賦給一個變 量。瀏覽器讓你這么做流部,但是解析的情況是不同的戚绕。
/*bad*/
if(currentUser){
function test(){
console.log('Nope.');
}
}
/*good*/
if(currentUser){
var test = function test(){
console.log('Yup.');
};
}
2、請勿把參數(shù)命名為 arguments,這會對函數(shù)內(nèi)的 arguments對象產(chǎn)生影響枝冀。
/*bad*/
function nope(name, options, arguments){
}
/*good*/
function yup(name, options, args){
}
- 條件表達(dá)式的強(qiáng)類型轉(zhuǎn)換規(guī)則:
對象被計算為true
Undefined被計算為false
Null被計算為false
布爾值被計算為布爾的值
數(shù)字如果是+0, -0,NaN被計算為false
字符如果是空字符串舞丛,則被計算為false,否則為true
字符串如果是空字符串果漾,則被計算為false球切,否則為true - 事件:當(dāng)給事件附加數(shù)據(jù)時,傳入一個哈希而不是原始值绒障,這可以讓后面的貢獻(xiàn)者加入更多數(shù)據(jù)到事件數(shù)據(jù) 里而不用找出并更新那個事件的事件處理器吨凑。
/*bad*/
$(this).trigger('listingUpdated', listing.id);
$(this).on('listingUpdated', function(e,listingId){
/*do something with listingId*/
});
/*good*/
$(this).trigger('listingUpdated', {listingId: listing.id});
$(this).on('listingUpdated', function(e, data){
/*do something with data.listingId*/
});
四、Summary.
本文申明户辱,內(nèi)容中多為作者從多篇優(yōu)質(zhì)文章中整合搜刮而來鸵钝,如有不當(dāng)之處,請多指正庐镐。為了自己以后查閱方便恩商,也為了有相同需求的朋友提供便利。最后必逆,愿你我像堅守做人的原則一樣怠堪,堅守標(biāo)準(zhǔn)的開發(fā)規(guī)范韧献。(當(dāng)然,我們可以在前人積累的經(jīng)驗上研叫,建立屬于自己的锤窑、更優(yōu)質(zhì)的開發(fā)規(guī)范。)