高质量的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事件。
但是按照以上的方法必须网页的全部的内容加载完才执行,如果页面很大,就要等很久的时间了,最好的方法就是只要DOM加载完成即可啦。DOMReady来啦。
DOMReady是结合框架来使用的,jquery的,就非常明了啦。
在调用init( )函数时候,更稳妥的方法。
文件压缩
最流行的压缩工具Packer和YUI 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
| function getNextNode(node){ node = typeof node == "string" ? document.getElementById(node) : node; var nextNode = node.nextSiblings; if(!nextNode) {return null;} 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; } </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]]; } } GLOBAL.namespace("DOM"); GLOBAL.DOM.getNextNode = ......
GLOBAL.namespace("Event"); GLOBAL.Event.getEventTarget = ......
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 |