为了方便团队其他人员的阅读本人代码,减少团队交流成本,提高工作效率。代码规范很重要,公司这段时间尤其对这一块重视。
本人对这块的学习改正重点为如下:
HTML
一,class和ID的命名问题:
1.应该以内容和功能命名,不要以表现形式命名。
2.字母为小写,多个字母时用中划线-分隔
3.ID为js hook,避免使用空的class样式
二,ID统一使用双引号
三,标签语意化
标签 | 语义 |
---|---|
<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选择器从右到左匹配的机制后,明白只要当前选择符的左边还有其他选择符,样式系统就会继续向左移动,直到找到和规则匹配的选择符,或者因为不匹配而退出。我们把最右边选择符称之为关键选择器。
1、避免使用通用选择器
2、避免使用标签或 class 选择器限制 id 选择器
3、避免使用标签限制 class 选择器
4、避免使用多层标签选择器。使用 class 选择器替换,减少css查找
/* Not recommended */ treeitem[mailfolder="true"] > treerow > treecell {…} /* Recommended */ .treecell-mailfolder {…}
5、避免使用子选择器
/* Not recommended */ treehead treerow treecell {…} /* Recommended */ treehead > treerow > treecell {…} /* Much to recommended */ .treecell-header {…}
6、使用继承
/* 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.2、1.4.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 事件封装组成。
原文:https://www.cnblogs.com/Webzhoushifa/p/9523613.html