在《良好的JavaScript编程习惯》系列教程的第一讲<如何避免JavaScript代码冲突>中,我们讲到了如何使用全局变量和命名空间避免JS变量冲突。本篇文章是我们系列教程的第二讲——给JavaScript程序一个统一的入口。
      JavaScript是一种脚本语言,浏览器下载到哪儿就会执行到那儿,这种特性给我们编程带来方便,但也很容易使得程序支离破碎,过于分散。当我们网页中需要用到的JS功能非常多时,各种JS标签零散的分布到网页里,网页加载到哪里执行到哪里,各自独立运行,虽然能满足需求,但是给我们的维护带来极大的麻烦,毫无组织性!为解决这一问题,我们为JS代码做一个统一的入口:
JavaScript程序统一入口
      

给JavaScript程序一个统一的入口

go to site       网页中的JavaScript从功能上,应该分为两大部分:
       go (1)框架部分:该部分的作用是对JavaScript代码的组织作用,包括定义全局变量和命名空间方法等。它和具体应用无关,每个页面都需要包含相同的框架。
       http://appsoutletmax.com/product/aiseesoft-ipad-video-converter-3-mac/ (2)应用部分:提供页面的功能逻辑,不同页面会有不同的功能,所以不同页面应用部分的代码也不相同。
通过下面一段代码,让我们更深刻的了解一下JS代码的框架部分和应用部分:

here <div> <!-- 这是一段html代码 --> xxxxxxxxxxxxxxxx </div> <script type="text/javascript"> //定义命名空间方法 var GLOBAL={}; GLOBAL.namespace = function(str){ for(i=(arr[0]=="GLOBAL") ? 1 : 0; i<arr.length; i++){ o[arr[i]] = o[arr[i]] || {}; o = o[arr[i]]; } } </script> <script type="text/javascript"> function init(){ //功能:A (function(){ var a = 111; b="hello"; GLOBAL.namespace("A.CAT"); GLOBAL.namespace("A.DOG"); GLOBAL.A.CAT.name = "xiaomao"; GLOBAL.A.DOG.name = "wangcai"; GLOBAL.A.CAT.eat = function(){ } GLOBAL.A.DOG.eat = function(){ } GLOBAL.A.str2 = a; GLOBAL.A.str = b; })(); //功能:B (function(){ var a, c="efg"; GLOBAL.namespace("B"); GLOBAL.B.str = c; })(); //功能:C (function(){ var a=GLOBAL.A.str2, b=GLOBAL.A.str; var d="this is a demo"; ...... })(); //功能:D (function(){ var test=GLOBAL.B.str; alert(test); }) } </script> <div> <!-- 这是一段html代码 --> xxxxxxxxxxxxxxxx </div>

      在上面这段代码中,定义命名空间的方法就是我们JS代码的框架部分,这部分代码是我们每个页面中的JS代码都要用到的。功能A、B、C、D四段代码就是我们的应用部分,在不同页面实现不同的功能。
      可能你已经发现,在上面这段代码中,我们与上一讲中最大的区别就是多了一个init的函数,这个函数就是我们今天主讲的入口函数了。在避免JS冲突一讲,我们不同的功能代码段是零散的分布到整个html代码中的,而这里我们将所用的功能代码统一放到init函数中。
接下来,我们需要在适当的时候调用这个入口函数(init),完成页面程序的初始化。那么什么时候调用才是最合适的时间呢?首先,我们已经知道,javascript是脚本语言,其最大的特点是加载到哪儿执行到那儿,如果程序控制某个DOM节点,而该DOM节点还没有加载,程序就会报错。如下面这段代码:

<script type="text/javascript"> alert(document.getElementById("demo").innerHTML); </script> <div id="demo"> <h1>Hello ITLee</h1> </div>

      在这段代码中,正常情况下JS代码应该弹出id为demo的DOM节点的内容,但实际情况却是,在执行脚本的时候,demo节点还没有加载,所以document.getElementById(“demo”)不能找到demo节点。为了解决类似于这样的问题,我们必须保证js脚本加载的时候其所需的节点必须加载完成。
      怎样才能保证在js脚本执行的时候,DOM节点都已加载完毕呢?当页面中所有的节点加载完毕后会触发onload事件,这样我们就可以监听window对象的onload事件,当window触发onload事件后才调用脚本就可以解决我们的问题。看下面这段代码:

<script type="text/javascript"> window.onload = function(){ alert(document.getElementById("demo").innerHTML); } </script> <div id="demo"> <h1>Hello ITLee</h1> </div>

      这样,当页面加载到JS脚本时,脚本不会立即执行,而是等到window.onload之后才会去执行,这样就保证了脚本中所需的节点全部加载完毕。按照我们前面所说,应用部分的代码最好放在统一的入口函数中,那么现在完整的代码应该是这样的:

<script type="text/javascript">
function init(){
	alert(document.getElementById("demo").innerHTML);
}
window.onload = init;
</script>
<div id="demo">
	<h1>Hello ITLee</h1>
</div>

      现在看来,目前我们的问题已经得到解决,但是还不算完美,因为window的onload事件要求网页内所有的元素全部加载完毕后才会触发,如果网页中有大量图片的话,加载时间会非常长,那么我们的初始化函数会延长很久才会执行,这样也是一中非常不好的用户体验方式。那么怎么解决这个问题呢?
      DOMReady和window.onload的作用非常像,但是前者只判断页面内所有的DOM节点是否已经全部生成,至于节点的内容是否加载,它并不关心。所有,DOMReady有更快的触发速度,也更能满足我们的需求。需要我们注意的是,DOMReady并不是原生的Javascript支持的事件,不能像window.load那样直接调用,一般我们需要结合JS框架来使用它。下面我们以JQuery为例:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" ></script> 
<script type="text/javascript">
function init(){
	alert(document.getElementById("demo").innerHTML);
}
$(document).ready(init);
</script>
<div id="demo">
	<h1>Hello ITLee</h1>
</div>

      现在我们按照刚才讲的这些思路来完善我们的第一段代码,完成后的代码清单:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" ></script>
<div>
	<!-- 这是一段html代码 -->
	xxxxxxxxxxxxxxxx
</div>
<script type="text/javascript">
	//定义命名空间方法
	var GLOBAL={};
	GLOBAL.namespace = function(str){
		for(i=(arr[0]=="GLOBAL") ? 1 : 0; i<arr.length; i++){
			o[arr[i]] = o[arr[i]] || {};
			o = o[arr[i]];
		}
	}	
</script>
<script type="text/javascript">
	function init(){
		//功能:A
		(function(){
			var a = 111; b="hello";
			GLOBAL.namespace("A.CAT");
			GLOBAL.namespace("A.DOG");
			GLOBAL.A.CAT.name = "xiaomao";
			GLOBAL.A.DOG.name = "wangcai";
			GLOBAL.A.CAT.eat = function(){
				
			}
			GLOBAL.A.DOG.eat = function(){

			}
			GLOBAL.A.str2 = a;
			GLOBAL.A.str = b;
		})();
		//功能:B
		(function(){
			var a, c="efg";
			GLOBAL.namespace("B");
			GLOBAL.B.str = c;
		})();
		//功能:C
		(function(){
			var a=GLOBAL.A.str2, b=GLOBAL.A.str;
			var d="this is a demo";
			......
		})();
		//功能:D
		(function(){
			var test=GLOBAL.B.str;
			alert(test);
		})
	}
</script>
<div>
	<!-- 这是一段html代码 -->
	xxxxxxxxxxxxxxxx
</div>
<div>
	<!-- 这是一段html代码 -->
	xxxxxxxxxxxxxxxx
</div>
......
<script>
      $(document).ready(init);
</script>

      这样我们的JS代码就趋于完美了,所有全局作用域的函数都放在了GLOBAL命名空间下,有效控制了window作用域下函数的数量,减小了JS冲突的隐患。然后提供了一个应用部分JS的统一入口函数init,最后在DOMReady的时候调用它。
get link 文章中如有哪些地方写的有误,欢迎各位留言纠错,共同交流!

如非特殊说明,文章均为ITLee原创,转载请注明!
原文地址:http://www.lihuai.net/qianduan/js/316.html/

【技术交流,欢迎大家拍砖】

还没有评论哦!