前端開發規範

前端開發規範

前端開發

1、HTML規範

1.1.使用正確的HTML5文檔類型

  1. <!doctype html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="renderer" content="webkit"> <!-- 360使用極速模式渲染 -->
  6. <title>Document</title>
  7. </head>
  8. <body>
  9. </body>
  10. </html>

1.2 兼容的meta屬性

  1. <meta name="renderer" content="webkit"> <!-- 360使用極速模式渲染 -->

1.3 統一使用4空格的tab縮進

1.4.避免不規範的元素嵌套

錯誤示例:

  1. <ul>
  2. <div>導航欄標題</div>
  3. <li>子項1</li>
  4. <li>子項2</li>
  5. <ul>

正確示例:

  1. <div>導航欄標題</div>
  2. <ul>
  3. <li>子項1</li>
  4. <li>子項2</li>
  5. <ul>

ul標籤只允許存在li作爲其直接子標籤。錯誤示例中的代碼雖然可以正常渲染,但是由於不同瀏覽器容錯機制不一致,錯誤的示例代碼可能會導致額外的hack。

1.5.自定義屬性採用data-*格式

錯誤示例:

  1. <div ng-click="click()">

正確示例:

  1. <div data-ng-click="click()">

data-*是HTML5的標準規範,如不採用data-*格式,IDE會顯示警告信息,避免警告信息影響正常的debug,建議採用data-*格式自定義屬性。

1.6.布爾類型的屬性,建議不添加屬性值

錯誤示例:

  1. <input type="checkbox" checked="true">
  2. <input type="checkbox" checked="flase">
  3. <input type="checkbox" checked="checked">

正確示例:

  1. <input type="checkbox" checked>

獲取選擇選中狀態,使用dom節點對象的checked屬性,或者jQuery的is方法,不要使用attr('checked')進行判斷。

錯誤做法:

  1. var $checkbox = $('input[checkbox]');
  2. $checkbox.attr("checked"); // 不準確,甚至會取得非預期值

正確做法:

  1. $checkbox.is(':checked');
  2. $checkbox.check = true;
  3. $checkbox.check;

2、CSS規範

2.1.確定全局唯一的元素,可以使用id,否則使用class

否則會導致後期維護成本過大。

2.2.選擇器應儘量避免嵌套,最多不過3級別

不好的做法:

  1. body #container .head .title {
  2. // code here
  3. }

推薦做法:

  1. .h-title {
  2. // code here
  3. }

嵌套過多,會導致css權重過大,子class跟父class緊耦合,後期維護成本大。

3、JavaScript規範

3.1.字符串統一使用單引號包含

不好的示例:

  1. var msg = "Hello JavaScript!";

正確示例:

  1. var msg = 'Hello JavaScript!';

使用單引號的最主要原因是,避免額外的單引號\雙引號轉義。

  1. var dom = “<div data-ng-click=\"click();\">雙引號\"\"不建議</div>”;

vs

  1. var dom = '<div data-ng-click="click();">雙引號""不建議</div>';

兩種寫法對比,優劣一目瞭然。

3.2.避免使用JavaScript拼接HTML

使用JavaScript拼接HTML,會有以下問題: 
* 極容易產生XSS漏洞; 
* 關注點不分離,升級維護極其困難; 
* 開發效率低下,代碼不健壯,非常容易產生bug; 
* Debug變的異常艱難;

不好的示例:

  1. var names = ['tiger','apple', '<script>alert("xss");</script>'];
  2. var dom = '<ul>';
  3. names.forEach(function(name,index){
  4. dom += '<li>' + name + '</li>';
  5. })
  6. dom += '</ul>';
  7. $('body').html(dom);

上面的代碼會導致一下問題: 
* names[2]插入頁面後,<script>alert("xss");<script>會被當成腳本執行,容易被用戶利用,入侵系統; 
* 代碼升級維護困難,如果要修改樣式,或者渲染的對象更加複雜(多層嵌套),維護這樣的代碼不僅效率低下,容易出錯,簡直就是噩夢; 
* 產生bug的情況下,調試異常複雜;

正確示例:

AngularJS寫法:

  1. <ul>
  2. <li data-ng-repeat="name in names">{{ name }}</li>
  3. </ul>

如果使用jQuery情況下,可以使用前端模板引擎,例如doT.js、jQuery Template等。

3.3 JavaScript語法技巧

使用這些小技巧,可以讓代碼更加簡潔、容易理解。

3.3.1 默認參數賦值

冗長寫法:

  1. function fun(param) {
  2. if(param == null) {
  3. param = {name:'tiger'};
  4. }
  5. }

簡潔寫法:

  1. function fun(param) {
  2. param = param || {name:'tiger'};
  3. }

3.3.2 判空執行

冗長寫法:

  1. function fun() {
  2. if(flag) {
  3. callback();
  4. }
  5. }

簡潔寫法:

  1. function fun() {
  2. flag && callback();
  3. }

3.3.3 自調用函數

冗長寫法:

  1. function fun(){
  2. // code here
  3. }
  4. fun();

簡潔寫法:

  1. (function(){
  2. // code here
  3. })();

3.3.4 數組迭代

冗長寫法:for

簡潔寫法:filter、some、every、forEach、map

3.3.4.2 filter:對數組進行過濾,並返回新的數組
  1. var s = [1,2,3,4,5];
  2. var ns = s.filter(function(item,index) {
  3. return item > 3;
  4. })
  5. console.log(ns); // [4,5]
3.3.4.3 some:判斷數組中是否有符合條件的元素
  1. var s = [1,2,3,4,5];
  2. var b = s.some(function(item,index) {
  3. return item > 3;
  4. })
  5. console.log(b); // true
3.3.4.4 every:判斷數組中所有元素是否都符合條件
  1. var s = [1,2,3,4,5];
  2. var b = s.every(function(item,index) {
  3. return item > 3;
  4. })
  5. console.log(b); // false
3.3.4.5 map:對數組中的元素進行處理,並返回新的數組
  1. var s = [1,2,3,4,5];
  2. var ns = s.map(function(item,index) {
  3. return item * 2;
  4. })
  5. console.log(ns); // [2,4,6,8,10]
3.3.4.6 forEach:迭代數組元素
  1. var s = [1,2,3,4,5];
  2. var ns = s.map(function(item,index) {
  3. console.log(item); // 依次打印1,2,3,4,5
  4. })

3.4. 前端開發的JavaScript技巧

3.4.1 使用Angular時,ajax請求請使用ng自帶的$http,避免使用jQuery的ajax

$http的ajax回調會自動更新DOM節點,而jQuery的回調沒有這個特徵,需要手動apply。

  1. <div>{{ user.username }}</div>

正確的jQuery寫法:

  1. $.post('/login',{username:'tiger',passwd='123456'},function(rs){
  2. $scope.user = rs.user;
  3. $scope.$apply();
  4. })

正確的AngularJS寫法:

  1. var params = {username:'tiger',passwd='123456'}
  2. $http({method : 'POST',url : '/login', data: $.param(params)
  3. }).then(function(rs) {
  4. $scope.user = rs.data.user;
  5. });

如果是GET請求,data則改成params,同時不需要$.param序列化,params的參數放url上,而data是放request body中。

  1. var params = {username:'tiger',passwd='123456'}
  2. $http({method : 'GET',url : '/login', params: params
  3. }).then(function(rs) {
  4. $scope.user = rs.data.user;
  5. });

3.4.2 HTTP請求中,獲取使用GET,提交、修改和刪除使用POST

這樣更加符合REST的語義,如果POST使用GET代替,在開發階段就難以調試,而且無法使用GET的特性進行一系列調優,例如緩存等。

HTTP中,GET/POST/DEL等的區別:http://www.cnblogs.com/zhangpengshou/archive/2012/07/09/2583096.html

3.4.3 獲取ajax的表單參數,jQuery可以將form表單序列化,Angualr可以綁定對象

推薦的jQuery寫法:

  1. <form id="loginFrom">
  2. <input name="username" type="text" />
  3. <input name="password" type="passwrod"/>
  4. </form>
  5. <script>
  6. var params = $('#loginForm').serialize();
  7. $.post('/login',params,function(rs){
  8. // callback
  9. });
  10. </script>

推薦的AngularJS寫法:

  1. <form>
  2. <input type="text" data-ng-model="loginForm.username" />
  3. <input type="passwrod" data-ng-model="loginForm.password"/>
  4. </form>
  5. <script>
  6. $http({
  7. method : 'POST',
  8. url : '/login',
  9. data: $.param($scope.loginForm)
  10. }).then(function(rs) {
  11. // callback
  12. });
  13. </script>

3.4.4 jQuey調用AngularJS的方法

思路:取得AngularJS作用域下的節點找到scope,通過scope調用方法:

  1. var container = $('#container'); // #containe要在data-ng-app的子節點下
  2. angular.element(container).scope().fun(); // 調用AngularJS下面的fun方法;

強烈推薦使用Angular開發,jQuery的功能基本95%以上都可以用Angular代替,代碼量更少,更容易維護。

4、AngularJS與JAVA EnumMap實現前後端統一

  1. public enum ChargeControlMode {
  2. BMS("bms", Constant.CHARGE_CONTROL_MODE_BMS),
  3. POWER("power", Constant.CHARGE_CONTROL_MODE_POWER),
  4. MONEY("money", Constant.CHARGE_CONTROL_MODE_MONEY),
  5. TIME("time", Constant.CHARGE_CONTROL_MODE_TIME);
  6. ...
  7. public static Map<String, String> buildEnumElementMap() {
  8. Map<String, String> chargeControlModeMap = new HashMap<String, String>();
  9. chargeControlModeMap.put(ChargeControlMode.BMS.name(), Constant.CHARGE_CONTROL_MODE_BMS);
  10. chargeControlModeMap.put(ChargeControlMode.POWER.name(), Constant.CHARGE_CONTROL_MODE_POWER);
  11. chargeControlModeMap.put(ChargeControlMode.MONEY.name(), Constant.CHARGE_CONTROL_MODE_MONEY);
  12. chargeControlModeMap.put(ChargeControlMode.TIME.name(), Constant.CHARGE_CONTROL_MODE_TIME);
  13. return chargeControlModeMap;
  14. }
  15. }
  1. @SuppressWarnings("rawtypes")
  2. @RequestMapping(value = "/buildAllEnumsMap", method = RequestMethod.GET)
  3. public ResponseEntity<Map<String, Map>> buildAllEnumsMap() {
  4. Map<String, Map> map = buildEnumElementsMap();
  5. if (map.isEmpty()) {
  6. return new ResponseEntity<Map<String, Map>>(HttpStatus.NO_CONTENT);
  7. }
  8. return new ResponseEntity<Map<String, Map>>(map, HttpStatus.OK);
  9. }
  10. /**
  11. * 構造充電樁參數相關的枚舉元素類型的Map<String, Map><br>
  12. * key->枚舉類型的名稱,如BillingType<br>
  13. * vale-> 是一個Map,包含枚舉類型的所有元素,key是枚舉元素名稱的變量,value是具體值<br>
  14. * @return 返回充電樁參數相關的枚舉類型Map<String, Map>
  15. */
  16. @SuppressWarnings("rawtypes")
  17. private Map<String, Map> buildEnumElementsMap() {
  18. Map<String, Map> map = new HashMap<String, Map>();
  19. //計費方式
  20. map.put(BillingType.class.getSimpleName(), BillingType.buildEnumElementMap());
  21. //充電控制模式
  22. map.put(ChargeControlMode.class.getSimpleName(), ChargeControlMode.buildEnumElementMap());
  23. return map;
  24. }
  1. that.buildAllEnumsMap = function(){
  2. $.eompTools.blockUI();
  3. $.eompAjaxService.doGet('/em/rest/stakeParm/buildAllEnumsMap', {}, function(resdata) {
  4. if (resdata) {
  5. that.enumsMap = resdata;
  6. }
  7. $.eompTools.unblockUI();
  8. });
  9. };
  10. <label class="col-md-4 control-lable" for="file"> 控制模式: </label>
  11. <span class="col-md-6 control-lable" for="file">
  12. {{ctrl.enumsMap.ChargeControlMode[ctrl.parameters.chargeConfig.chargeControlMode]}}
  13. 等價於
  14. {{ctrl.enumsMap.ChargeControlMode['TIME']}}
  15. </span>
  16. ==> 控制模式:時間控制
發佈了18 篇原創文章 · 獲贊 3 · 訪問量 5405
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章