前端代码规范-js

目录
  1. 高质量的javascript
    1. 养成良好的编程习惯
    2. 给程序统一的入口
    3. 文件压缩
  2. javascript的分层概念和javascript库
    1. 如何分层

高质量的javascript

养成良好的编程习惯

  • 用匿名函数将脚本包起来,可以有效控制全局变量,避免冲突隐患。
  • 使用命名空间
1
2
3
4
5
6
7
8
9
10
11
<script>
var GLOBAL = {};
</script>

<script>
(function(){
var a=123,b="hello world";
GLOBAL.A={};
GLOBAL.A.str2 = a;
GLOBAL.A.str = b;
})
</script>

  • 给代码添加适当的注释,以提高代码的可维护性。

添加必要的注释,可以大大的提高代码的可维护性,对于团队合作来说,更是十分有必要的。
让js不产生冲突,需要避免全局变量的泛滥,合理使用命名空间以及为代码添加必要的注释。

给程序统一的入口

window.onload和DOMReady
js从功能上分:框架部分和应用部分。

  • 框架部分:提供的是将js代码的组织作用,包括定义全局变量,定义命名空间。
  • 应用部分:页面逻辑功能,不同的页面会有不同的功能,不同页面的应用部分的代码也不相同。

现在给定一个“入口”,init( )就是一个入口。

1
2
3
4
5
6
function init(){
(function(){
xxx;
})();
xxx;
}

window.onload( )会在window对象在网页内元素全部加载完毕之后触发onload事件。

1
window.onload = init;

但是按照以上的方法必须网页的全部的内容加载完才执行,如果页面很大,就要等很久的时间了,最好的方法就是只要DOM加载完成即可啦。DOMReady来啦。
DOMReady是结合框架来使用的,jquery的,就非常明了啦。

在调用init( )函数时候,更稳妥的方法。

1
if(init){init( );}

文件压缩

最流行的压缩工具PackerYUI Compresser

javascript的分层概念和javascript库

如何分层

分层可以让我们的代码组织条理更清晰,减少冗余,提高代码重用率。
推荐:base.js + common.js + page.js
1.base.js
最底层,职责:

  • 封装不同浏览器下js的差异,提供统一的接口,完成兼容性的工作。
  • 扩展js语言底层提供的接口。
  • 给base.js和commmon.js提供接口。

兼容性解决整理:

1.FireFox会将空白,换行等文本信息也仿作childNodes中的一员,而IE则会忽略,只将DOM节点当做childNodes的一员。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//兼容浏览器的nextSiblings的函数封装。
function getNextNode(node){
node = typeof node == "string" ? document.getElementById(node) : node;
var nextNode = node.nextSiblings;
//判断是否有nextSiblings
if(!nextNode) {return null;}
//判断是否是IE浏览器。
if(!document.all){
while(true){
if(nextNode.nodeType == 1){
break;
}else{
if(nextNode.nextSiblings){
nextNode = nextNode.nextSiblings;
}else{
break;
}
}
}
}
};

2.透明度,IE的透明度是通过滤镜实现的,而FireFox是通过opacity属性值得数值而来的。

1
2
3
4
5
6
7
8
function setOpacity(node, lebel){
var node = typeof node == "string" ? document.getElementById(node) : node;
if(document.all){
node.style.filter = 'alpha(opacity=' + level + ')';
}else{
node.style.opacity = level / 100;
}
}

3.event对象,Ie中event对象是作为window的属性作用于全局作用域的,而在firefox中,event对象是作为事件的参数存在的。

1
2
3
4
function getEventTarget(e){
e = window.event || e;
return e.srcElement || e.target;
}

4.冒泡:阻止冒泡在IE中是event对象的cancelBubble属性设置为true;而其他是调用event对象的stopPropagation()方法实现的。

1
2
3
4
5
6
7
8
9
10
<script>
function stopPagation(e){
e = window.event || e;
if(document.all){
e.cancelBubble = true;
}else{
e.stopPagation();
}
}
</script>

5.attachEvent和addEventListener支持事件的叠加,可以解决用onxxx带来的叠加冲突问题。

1
2
3
4
5
6
7
8
9
10
<script>
function on(node, eventType, handle){
node = typeof node =="string" ? document.getElementById(node) : node;
if(document.all){
node.attachEvent("on"+eventType,handler);
} else {
node.addEventListener("on"+eventType, handler, false);
}
}
</script>

扩展js底层的接口:
接口不丰富:没有extend方法,以及也没有getElemenByClassName()。

1.trim()去除字符串首尾的空格,原生js不存在,扩展。

1
2
3
4
5
<script>
function trim(ostr){
return ostr.replace(/^\s+|\s+$/, "");
}
</script>

2.get()和$()

1
2
3
4
5
6
7
8
9
10
11
<script>
function get(node){
node = typeof node =="string" ? document.getElementById(node) : node;
return node;
}
function $(node){
node = typeof node =="string" ? document.getElementById(node) : node;
return node;
}
// alert($("huang").innerHTML);
</script>

3.getElementByClassName():自定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
function getElementByClassName(str, root, tag){
if(root){
root = typeof root == "string" ? document.getElementById(root) : root;
} else {
root = document.body;
}
tag = tag || "*";
var els = root.getElementByTagName(tag),arr = [];
for(var i=0,n=els.length;i<n;i++){
for(var j=0,k=els[i].className.split(" "),l=k.length;j<l;j++){
if(k[j] == str){
arr.push(els[i]);
break;
}
}
}
return arr;
}
</script>

base层使用命名空间:
接口可以分为三类:操作DOM、操作事件和从其他模仿原生js没有的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script>
var GLOBAL = {};
GLOBAL.namespace = function(str){
var arr = str.split("."), o = GLOBAL;
for(var i =(arr[0]=="GLOBAL") ? 1 : 0; i<arr.length; i++){
o[arr[i]] = o[arr[i]] || {};
o = o[arr[i]];
}
}
// DOM相关
GLOBAL.namespace("DOM");
GLOBAL.DOM.getNextNode = ......

// event相关
GLOBAL.namespace("Event");
GLOBAL.Event.getEventTarget = ......

//lang相关
GLOBAL.namespace("Lang");
GLOBAL.Lang.trim = ......

</script>

2.common.js

  • 提供可供复用的组件。
  • mvc模式中的m,和页面内的具体功能没有直接的关系。
  • 给page.js层提供组件。

书籍示例是一个关于cookie。

commom.js提供的组件不像base那么通用,它和具体功能有关,如果页面不需要就不用加载。而且一个易用性、重用性和可扩展性都非常好的组件,代码量往往偏高,所以common层的js需要按照功能分成一个个独立的文件。命名common_xxx.js。

3.page.js

  • mvc模式中的c。
  • 依赖于base.js和common.js
  • 完成页面内的功能需求。

复议一下:现在流行的js库。
prototype | Dojo | MOotools | Ext JS | jQuery | YUI |