前端代码规范的笔记(一)

为了方便团队其他人员的阅读本人代码,减少团队交流成本,提高工作效率。代码规范很重要,公司这段时间尤其对这一块重视。

本人对这块的学习改正重点为如下:

 


 

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命名

  • 使用语义化、通用的命名方式;
  • 使用连字符 - 作为 ID、Class 名称界定符,不要驼峰命名法和下划线;
  • 避免选择器嵌套层级过多,尽量少于 3 级;
  • 避免选择器和 Class、ID 叠加使用;

避免class,ID和选择器混合式使用,若改了class名称还要去改CSS代码,不利于后期的维护

二,声明块格式

  • 选择器分组时,保持独立的选择器占用一行;
  • 声明块的左括号 { 前添加一个空格;
  • 声明块的右括号 } 应单独成行;
  • 声明语句中的 : 后应添加一个空格;
  • 声明语句应以分号 ; 结尾;
  • 一般以逗号分隔的属性值,每个逗号后应添加一个空格;
  • rgb()rgba()hsl()hsla() 或 rect() 括号内的值,逗号分隔,但逗号后不添加一个空格;
  • 对于属性值或颜色参数,省略小于 1 的小数前面的 0 (例如,.5 代替 0.5-.5px 代替 -0.5px);
  • 十六进制值应该全部小写和尽量简写,例如,#fff 代替 #ffffff
  • 避免为 0 值指定单位,例如,用 margin: 0; 代替 margin: 0px;

三,声明顺序

相关属性应为一组,推荐的样式编写顺序

  1. Positioning(由于定位(positioning)可以从正常的文档流中移除元素,并且还能覆盖盒模型(box model)相关的样式,因此排在首位)
  2. Box model(盒模型决定了组件的尺寸和位置,因此排在第二位)
  3. Typographic(排版相关)
  4. Visual(视觉)
  5. Other(其他)

四,引号的使用

  1. 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的性能优化

一,慎重选择高消耗的样式

  • box-shadows
  • border-radius
  • transparency(透明)
  • transforms(动画)
  • CSS filters(滤镜 性能杀手)

二,避免重排列

  • width
  • height
  • padding
  • margin
  • display
  • border-width
  • position
  • top
  • left
  • right
  • bottom
  • font-size
  • float
  • text-align
  • overflow-y
  • font-weight
  • overflow
  • font-family
  • line-height
  • vertical-align
  • clear
  • white-space
  • min-height

三,正确的使用display属性

Display 属性会影响页面的渲染,请合理使用。

  • display: inline后不应该再使用 width、height、margin、padding 以及 float;

  • display: inline-block 后不应该再使用 float;

  • display: block 后不应该再使用 vertical-align;

  • display: table-* 后不应该再使用 margin 或者 float;

四,不滥用float

五,动画性能的优化

动画的基本概念:

  • 帧:在动画过程中,每一幅静止画面即为一“帧”;
  • 帧率:即每秒钟播放的静止画面的数量,单位是fps(Frame per second);
  • 帧时长:即每一幅静止画面的停留时间,单位一般是ms(毫秒);
  • 跳帧(掉帧/丢帧):在帧率固定的动画中,某一帧的时长远高于平均帧时长,导致其后续数帧被挤压而丢失的现象。

一般浏览器的渲染刷新频率是 60 fps,所以在网页当中,帧率如果达到 50-60 fps 的动画将会相当流畅,让人感到舒适。

  • 如果使用基于 javaScript 的动画,尽量使用 requestAnimationFrame. 避免使用 setTimeout, setInterval.
  • 避免通过类似 jQuery animate()-style 改变每帧的样式,使用 CSS 声明动画会得到更好的浏览器优化。
  • 使用 translate 取代 absolute 定位就会得到更好的 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

一,注释

原则:

  • As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性、可读性。
  • As long as necessary(如有必要,尽量详尽):合理的注释、空行排版等,可以让代码更易阅读、更具美感。

1. 单行注释

必须独占一行。// 后跟一个空格,缩进与下一行被注释说明的代码一致。

2. 多行注释

避免使用 /*...*/ 这样的多行注释。有多行注释内容时,使用多个单行注释。

3. 函数/方法注释

  1. 函数/方法注释必须包含函数说明,有参数和返回值时必须使用注释标识。;
  2. 参数和返回值注释必须包含类型信息和说明;
  3. 当函数是内部函数,外部不可访问时,可以使用 @inner 标识;
/**
 * 函数描述
 *
 * @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.
 */

二,命名

变量

  1. 变量使用‘驼峰’命名法
  2. 私有属性、变量和方法以下划线 _ 开头。
  3. 常量, 使用全部字母大写,单词间下划线分隔的命名方式。

函数

  函数:

  1. 函数, 使用 Camel 命名法。
  2. 函数的参数, 使用 Camel 命名法。

  类

  1. , 使用 Pascal 命名法
  2. 类的 方法 / 属性, 使用 Camel 命名法

  枚举属性

  1. 枚举变量 使用 Pascal 命名法。
  2. 枚举的属性, 使用全部字母大写,单词间下划线分隔的命名方式。

  由多个单词组成的 缩写词,在命名中,根据当前命名法和出现的位置,所有字母的大小写与首字母的大小写保持一致。

三,命名语法
  1. 类名,使用名词。
  2. 函数名,使用动宾短语。
  3. boolean 类型的变量使用 is 或 has 开头。
  4. Promise 对象用动宾短语的进行时表达。

四,接口命名规范

  1. 可读性强,见名晓义;
  2. 尽量不与 jQuery 社区已有的习惯冲突;
  3. 尽量写全。不用缩写,除非是下面列表中约定的;(变量以表达清楚为目标,uglify 会完成压缩体积工作)
常用词说明
options表示选项,与 jQuery 社区保持一致,不要用 config, opts 等
active表示当前,不要用 current 等
index表示索引,不要用 idx 等
trigger触点元素
triggerType触发类型、方式
context表示传入的 this 对象
object推荐写全,不推荐简写为 o, obj 等
element推荐写全,不推荐简写为 el, elem 等
length不要写成 len, l
prevprevious 的缩写
nextnext 下一个
constructor不能写成 ctor
easing示动画平滑函数
minminimize 的缩写
maxmaximize 的缩写
DOM不要写成 dom, Dom
.hbs使用 hbs 后缀表示模版
btnbutton 的缩写
link超链接
title主要文本
img图片路径(img标签src属性)
datasethtml5 data-xxx 数据接口
theme主题
className类名
classNameSpaceclass 命名空间

五,True 和 False 布尔表达式

类型检测优先使用 typeof。对象类型检测使用 instanceof。null 或 undefined 的检测使用 == null。

下面的布尔表达式都返回 false:

  • null
  • undefined
  • '' 空字符串
  • 0 数字0

但小心下面的, 可都返回 true:

  • '0' 字符串0
  • [] 空数组
  • {} 空对象
六,不要在 Array 上使用 for-in 循环

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。以下是三条常见的 jQuery 语句,版本越新,性能越好

$('.elem')
$('.elem', context)
context.find('.elem')

 分别使用 1.4.2、1.4.4、1.6.2 三个版本测试浏览器在一秒内能够执行多少次,结果 1.6.2 版执行次数远超两个老版本。

二,jQuery 变量
  1. 存放 jQuery 对象的变量以 $ 开头;
  2. 将 jQuery 选择器返回的对象缓存到本地变量中复用;
  3. 使用驼峰命名变量;
var $myDiv = $("#myDiv");
$myDiv.click(function(){...});

三,选择器

  1. 尽可能的使用 ID 选择器,因为它会调用浏览器原生方法 document.getElementById 查找元素。当然直接使用原生 document.getElementById 方法性能会更好;
  2. 在父元素中选择子元素使用 .find() 方法性能会更好, 因为 ID 选择器没有使用到 Sizzle 选择器引擎来查找元素;
// Not recommended
var $productIds = $("#products .class");

// Recommended
var $productIds = $("#products").find(".class");

四,DOM 操作

  1. 当要操作 DOM 元素的时候,尽量将其分离节点,操作结束后,再插入节点;
  2. 使用字符串连接或 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(''));

五,事件

  1. 如果需要,对事件使用自定义的 namespace,这样容易解绑特定的事件,而不会影响到此 DOM 元素的其他事件监听;
  2. 对 Ajax 加载的 DOM 元素绑定事件时尽量使用事件委托。事件委托允许在父元素绑定事件,子代元素可以响应事件,也包括 Ajax 加载后添加的子代元素;
$("#myLink").on("click.mySpecialClick", myEventHandler);
$("#myLink").unbind("click.mySpecialClick");
// Not recommended
$("#list a").on("click", myClickHandler);

// Recommended
$("#list").on("click", "a", myClickHandler);

六,链式写法

  1. 尽量使用链式写法而不是用变量缓存或者多次调用选择器方法;
  2. 当链式写法超过三次或者因为事件绑定变得复杂后,使用换行和缩进保持代码可读性;
$("#myDiv").addClass("error").show();
$("#myLink")
  .addClass("bold")
  .on("click", myClickHandler)
  .on("mouseover", myMouseOverHandler)
  .show();

七,其他

  1. 多个参数使用对象字面量存储;
  2. 不要将 CSS 写在 jQuery 里面;
  3. 正则表达式仅准用 .test() 和 .exec() 。不准用 "string".match() ;

八,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实现动画

  1. 禁止使用 slideUp/Down() fadeIn/fadeOut() 等方法;
  2. 尽量不使用 animate() 方法;

 


 

 

移动端优化

移动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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值