爲了方便團隊其餘人員的閱讀本人代碼,減小團隊交流成本,提升工做效率。代碼規範很重要,公司這段時間尤爲對這一塊重視。css
本人對這塊的學習改正重點爲以下:html
HTMLhtml5
一,class和ID的命名問題:java
1.應該之內容和功能命名,不要以表現形式命名。node
2.字母爲小寫,多個字母時用中劃線-分隔jquery
3.ID爲js hook,避免使用空的class樣式git
二,ID統一使用雙引號github
三,標籤語意化web
標籤 | 語義 |
---|---|
<p> |
段落 |
<h1> <h2> <h3> ... |
標題 |
<ul> |
無序列表 |
<ol> |
有序列表 |
<blockquote> |
大段引用 |
<cite> |
通常引用 |
<b> |
爲樣式加粗而加粗 |
<storng> |
爲強調內容而加粗 |
<i> |
爲樣式傾斜而傾斜 |
<em> |
爲強調內容而傾斜 |
code |
代碼標識 |
abbr |
縮寫 |
能夠看看這個百度文庫裏面的優秀文件:https://wenku.baidu.com/view/0a8d3774f242336c1eb95ea9.html正則表達式
四,HEAD
HEAD模版<!DOCTYPE html>
<html lang="zh-cmn-Hans"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>Style Guide</title>
<!-- SEO優化 -->
<meta name="description" content="不超過150個字符"> <meta name="keywords" content=""> <meta name="author" content="name, email@gmail.com"> <!-- 爲移動設備添加 viewport --> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- iOS 圖標 --> <link rel="apple-touch-icon-precomposed" href="/apple-touch-icon-57x57-precomposed.png"> <link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml" /> <link rel="shortcut icon" href="path/to/favicon.ico"> </head>
1.語言屬性的設置
<!-- 中文 --> <html lang="zh-Hans"> <!-- 簡體中文 --> <html lang="zh-cmn-Hans"> <!-- 繁體中文 --> <html lang="zh-cmn-Hant"> <!-- English --> <html lang="en">
2.字符編碼
utf-8
3.IE兼容模式
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
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>
5.viewport
<meta name="viewport" content="width=device-width, initial-scale=1.0">
viewport
: 通常指的是瀏覽器窗口內容區的大小,不包含工具條、選項卡等內容;width
: 瀏覽器寬度,輸出設備中的頁面可見區域寬度;device-width
: 設備分辨率寬度,輸出設備的屏幕可見寬度;initial-scale
: 初始縮放比例;maximum-scale
: 最大縮放比例;6.favicon
link指定favicon.ico文件
<link rel="shortcut icon" href="path/to/favicon.ico">
CSS
良好的註釋是很是重要的。請留出時間來描述組件(component)的工做方式、侷限性和構建它們的方法。不要讓你的團隊其它成員 來猜想一段不通用或不明顯的代碼的目的。
彙總:
Components
的角度思考,以兩個單詞命名(.screenshot-image
)Components
中的 Elements
,以一個單詞命名(.blog-post .title
)Variants
,以中劃線-
做爲前綴(.shop-banner.-with-icon
)Components
能夠互相嵌套一,class和ID命名
避免class,ID和選擇器混合式使用,若改了class名稱還要去改CSS代碼,不利於後期的維護
二,聲明塊格式
{
前添加一個空格;}
應單獨成行;:
後應添加一個空格;;
結尾;rgb()
、rgba()
、hsl()
、hsla()
或 rect()
括號內的值,逗號分隔,但逗號後不添加一個空格;.5
代替 0.5
;-.5px
代替 -0.5px
);#fff
代替 #ffffff
;margin: 0;
代替 margin: 0px;
;三,聲明順序
相關屬性應爲一組,推薦的樣式編寫順序
四,引號的使用
url()
、屬性選擇符、屬性值使用雙引號。五,媒體查詢(Media query)的位置
將媒體查詢放在儘量相關規則的附近。不要將他們打包放在一個單同樣式文件中或者放在文檔底部。若是你把他們分開了,未來只會被你們遺忘。
六,不要使用 @import
七,Components
最少以兩個單詞命名,經過 -
分離
.like-button
).search-form
).article-card
)八,Elements
是 Components
中的元素 Elements 命名就用一個單詞;
.search-form { > .field { /* ... */ } > .action { /* ... */ } }
對於假若須要兩個或以上單詞表達的 Elements
類名,不該使用中劃線和下劃線鏈接,應直接鏈接。
.profile-box { > .firstname { /* ... */ } > .lastname { /* ... */ } > .avatar { /* ... */ } }
任什麼時候候儘量使用 classnames
。標籤選擇器在使用上沒有問題,可是其性能上稍弱,而且表意不明確。避免使用標籤選擇器。
假若你須要爲組件設置定位,應將在組件的上下文(父元素)中進行處理,好比如下例子中,將 widths
和 floats
應用在 list component(.article-list)
當中,而不是 component(.article-card)
自身。
當出現多個嵌套的時候容易失去控制,應保持不超過一個嵌套。
關於CSS的性能優化
一,慎重選擇高消耗的樣式
二,避免重排列
三,正確的使用display屬性
Display 屬性會影響頁面的渲染,請合理使用。
display: inline後不該該再使用 width、height、margin、padding 以及 float;
display: inline-block 後不該該再使用 float;
display: block 後不該該再使用 vertical-align;
display: table-* 後不該該再使用 margin 或者 float;
四,不濫用float
五,動畫性能的優化
動畫的基本概念:
通常瀏覽器的渲染刷新頻率是 60 fps,因此在網頁當中,幀率若是達到 50-60 fps 的動畫將會至關流暢,讓人感到溫馨。
六,多利用硬件能力,如經過 3D 變形開啓 GPU 加速
通常在 Chrome 中,3D或透視變換(perspective transform)CSS屬性和對 opacity 進行 CSS 動畫會建立新的圖層,在硬件加速渲染通道的優化下,GPU 完成 3D 變形等操做後,將圖層進行復合操做(Compesite Layers),從而避免觸發瀏覽器大面積重繪和重排。
七,提高CSS選擇器的性能
理解了CSS選擇器從右到左匹配的機制後,明白只要當前選擇符的左邊還有其餘選擇符,樣式系統就會繼續向左移動,直到找到和規則匹配的選擇符,或者由於不匹配而退出。咱們把最右邊選擇符稱之爲關鍵選擇器。
一、避免使用通用選擇器
二、避免使用標籤或 class 選擇器限制 id 選擇器
三、避免使用標籤限制 class 選擇器
四、避免使用多層標籤選擇器。使用 class 選擇器替換,減小css查找
/* Not recommended */ treeitem[mailfolder="true"] > treerow > treecell {…} /* Recommended */ .treecell-mailfolder {…}
五、避免使用子選擇器
/* Not recommended */ treehead treerow treecell {…} /* Recommended */ treehead > treerow > treecell {…} /* Much to recommended */ .treecell-header {…}
六、使用繼承
/* Not recommended */ #bookmarkMenuItem > .menu-left { list-style-image: url(blah) } /* Recommended */ #bookmarkMenuItem { list-style-image: url(blah) }
JavaScript
一,註釋
原則:
1. 單行註釋
必須獨佔一行。//
後跟一個空格,縮進與下一行被註釋說明的代碼一致。
2. 多行註釋
避免使用 /*...*/
這樣的多行註釋。有多行註釋內容時,使用多個單行註釋。
3. 函數/方法註釋
/** * 函數描述 * * @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 }; }
4. 文件註釋
文件註釋用於告訴不熟悉這段代碼的讀者這個文件中包含哪些東西。 應該提供文件的大致內容, 它的做者, 依賴關係和兼容性信息。以下:
/** * @fileoverview Description of file, its uses and information * about its dependencies. * @author user@meizu.com (Firstname Lastname) * Copyright 2009 Meizu Inc. All Rights Reserved. */
二,命名
變量
函數
函數:
類
枚舉屬性
由多個單詞組成的 縮寫詞,在命名中,根據當前命名法和出現的位置,全部字母的大小寫與首字母的大小寫保持一致。
四,接口命名規範
經常使用詞 | 說明 |
---|---|
options | 表示選項,與 jQuery 社區保持一致,不要用 config, opts 等 |
active | 表示當前,不要用 current 等 |
index | 表示索引,不要用 idx 等 |
trigger | 觸點元素 |
triggerType | 觸發類型、方式 |
context | 表示傳入的 this 對象 |
object | 推薦寫全,不推薦簡寫爲 o, obj 等 |
element | 推薦寫全,不推薦簡寫爲 el, elem 等 |
length | 不要寫成 len, l |
prev | previous 的縮寫 |
next | next 下一個 |
constructor | 不能寫成 ctor |
easing | 示動畫平滑函數 |
min | minimize 的縮寫 |
max | maximize 的縮寫 |
DOM | 不要寫成 dom, Dom |
.hbs | 使用 hbs 後綴表示模版 |
btn | button 的縮寫 |
link | 超連接 |
title | 主要文本 |
img | 圖片路徑(img標籤src屬性) |
dataset | html5 data-xxx 數據接口 |
theme | 主題 |
className | 類名 |
classNameSpace | class 命名空間 |
五,True 和 False 布爾表達式
類型檢測優先使用 typeof。對象類型檢測使用 instanceof。null 或 undefined 的檢測使用 == null。
下面的布爾表達式都返回 false:
但當心下面的, 可都返回 true:
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]); } }
七,二元和三元操做符
操做符始終寫在前一行, 以避免分號的隱式插入產生預想不到的問題。
var x = a ? b : c; var y = a ? longButSimpleOperandB : longButSimpleOperandC; var z = a ? moreComplicatedB : moreComplicatedC;
.
操做符也是如此:
var x = foo.bar(). doSomething(). doSomethingElse();
八,條件(三元)操做符(?:)
三元操做符用於替代 if 條件判斷語句。
// Not recommended if (val != 0) { return foo(); } else { return bar(); } // Recommended return val ? foo() : bar();
二元布爾操做符是可短路的, 只有在必要時纔會計算到最後一項。
// 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); }
jQuery規範
最新版本的 jQuery 會改進性能和增長新功能,若不是爲了兼容舊瀏覽器,建議使用最新版本的 jQuery。如下是三條常見的 jQuery 語句,版本越新,性能越好
$('.elem') $('.elem', context) context.find('.elem')
分別使用 1.4.二、1.4.四、1.6.2 三個版本測試瀏覽器在一秒內可以執行多少次,結果 1.6.2 版執行次數遠超兩個老版本。
$
開頭;var $myDiv = $("#myDiv"); $myDiv.click(function(){...});
三,選擇器
document.getElementById
查找元素。固然直接使用原生 document.getElementById
方法性能會更好;.find()
方法性能會更好, 由於 ID 選擇器沒有使用到 Sizzle 選擇器引擎來查找元素;// Not recommended var $productIds = $("#products .class"); // Recommended var $productIds = $("#products").find(".class");
四,DOM 操做
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(''));
五,事件
namespace
,這樣容易解綁特定的事件,而不會影響到此 DOM 元素的其餘事件監聽;$("#myLink").on("click.mySpecialClick", myEventHandler);
$("#myLink").unbind("click.mySpecialClick");
// Not recommended $("#list a").on("click", myClickHandler); // Recommended $("#list").on("click", "a", myClickHandler);
六,鏈式寫法
$("#myDiv").addClass("error").show();
$("#myLink") .addClass("bold") .on("click", myClickHandler) .on("mouseover", myMouseOverHandler) .show();
七,其餘
八,jQuery插件模版
// jQuery Plugin Boilerplate // A boilerplate for jumpstarting jQuery plugins development // version 1.1, May 14th, 2011 // by Stefan Gabos // remember to change every instance of "pluginName" to the name of your plugin! (function($) { // here we go! $.pluginName = function(element, options) { // plugin's default options // this is private property and is accessible only from inside the plugin var defaults = { foo: 'bar', // if your plugin is event-driven, you may provide callback capabilities // for its events. execute these functions before or after events of your // plugin, so that users may customize those particular events without // changing the plugin's code onFoo: function() {} } // to avoid confusions, use "plugin" to reference the // current instance of the object var plugin = this; // this will hold the merged default, and user-provided options // plugin's properties will be available through this object like: // plugin.settings.propertyName from inside the plugin or // element.data('pluginName').settings.propertyName from outside the plugin, // where "element" is the element the plugin is attached to; plugin.settings = {} var $element = $(element), // reference to the jQuery version of DOM element element = element; // reference to the actual DOM element // the "constructor" method that gets called when the object is created plugin.init = function() { // the plugin's final properties are the merged default and // user-provided options (if any) plugin.settings = $.extend({}, defaults, options); // code goes here } // public methods // these methods can be called like: // plugin.methodName(arg1, arg2, ... argn) from inside the plugin or // element.data('pluginName').publicMethod(arg1, arg2, ... argn) from outside // the plugin, where "element" is the element the plugin is attached to; // a public method. for demonstration purposes only - remove it! plugin.foo_public_method = function() { // code goes here } // private methods // these methods can be called only from inside the plugin like: // methodName(arg1, arg2, ... argn) // a private method. for demonstration purposes only - remove it! var foo_private_method = function() { // code goes here } // fire up the plugin! // call the "constructor" method plugin.init(); } // add the plugin to the jQuery.fn object $.fn.pluginName = function(options) { // iterate through the DOM elements we are attaching the plugin to return this.each(function() { // if plugin has not already been attached to the element if (undefined == $(this).data('pluginName')) { // create a new instance of the plugin // pass the DOM element and the user-provided options as arguments var plugin = new $.pluginName(this, options); // in the jQuery version of the element // store a reference to the plugin object // you can later access the plugin and its methods and properties like // element.data('pluginName').publicMethod(arg1, arg2, ... argn) or // element.data('pluginName').settings.propertyName $(this).data('pluginName', plugin); } }); } })(jQuery);
九,性能優化
1,避免沒必要要的 DOM 操做
瀏覽器遍歷 DOM 元素的代價是昂貴的。最簡單優化 DOM 樹查詢的方案是,當一個元素出現屢次時,將它保存在一個變量中,就避免屢次查詢 DOM 樹了。
// Recommended var myList = ""; var myListHTML = document.getElementById("myList").innerHTML; for (var i = 0; i < 100; i++) { myList += "<span>" + i + "</span>"; } myListHTML = myList; // Not recommended for (var i = 0; i < 100; i++) { document.getElementById("myList").innerHTML += "<span>" + i + "</span>"; }
2,緩存數組的長度
循環無疑是和 JavaScript 性能很是相關的一部分。經過存儲數組的長度,能夠有效避免每次循環從新計算。
注: 雖然現代瀏覽器引擎會自動優化這個過程,可是不要忘記還有舊的瀏覽器。
var arr = new Array(1000), len, i; // Recommended - size is calculated only 1 time and then stored for (i = 0, len = arr.length; i < len; i++) { } // Not recommended - size needs to be recalculated 1000 times for (i = 0; i < arr.length; i++) { }
3,異步加載第三方內容
當你沒法保證嵌入第三方內容好比 Youtube 視頻或者一個 like/tweet 按鈕能夠正常工做的時候,你須要考慮用異步加載這些代碼,避免阻塞整個頁面加載。
(function() { var script, scripts = document.getElementsByTagName('script')[0]; function load(url) { script = document.createElement('script'); script.async = true; script.src = url; scripts.parentNode.insertBefore(script, scripts); } load('//apis.google.com/js/plusone.js'); load('//platform.twitter.com/widgets.js'); load('//s.widgetsite.com/widget.js'); }());
4,避免使用jQuery實現動畫
移動端優化
移動Web問題小結
http://www.alloyteam.com/2015/06/yi-dong-web-wen-ti-xiao-jie/
移動端統計
https://github.com/jtyjty99999/mobileTech
關於無線端Web解決方案
http://am-team.github.io/about/about.html
click 的300ms延遲響應
click 事件由於要等待雙擊確認,會有 300ms 的延遲,體驗並非很好。
開發者大多數會使用封裝的 tap 事件來代替click 事件,所謂的 tap 事件由 touchstart 事件 + touchmove 判斷 + touchend 事件封裝組成。