500 likes | 684 Views
Javascript 的分层概念. 曹刘阳 (阿当). 目录. 原生 javascript. 底层、组件层和应用层. YUI2. JQuery. YUI3. 原生 javascript. 变量冲突:. < input type="button" value="click me" id="btn" /> <script type="text/javascript"> // 功能 A var a = 1,btn = document.getElementById("btn"); btn.onclick = function(){ a++;
E N D
Javascript的分层概念 曹刘阳 (阿当)
目录 原生javascript 底层、组件层和应用层 YUI2 JQuery YUI3
变量冲突: <input type="button" value="click me" id="btn" /> <script type="text/javascript"> // 功能A var a = 1,btn = document.getElementById("btn"); btn.onclick = function(){ a++; alert(a); // 101、102、103… } </script> ... <script type="text/javascript"> // 功能B var a = 100; //在此处被重新赋值 </script>
变量暴露在window作用域下,多人合作\多个功能间互相干扰。变量暴露在window作用域下,多人合作\多个功能间互相干扰。
DOM相关-1: <ul id="list"> <li id="firstItem">111</li> <li>222</li> <li>333</li> </ul> <script type="text/javascript"> var list = document.getElementById("list") , firstItem = document.getElementById("firstItem"); alert(firstItem.nextSibling.innerHTML); // IE : 222 firefox : undefined alert(list.childNodes.length); // IE : 3 firefox : 7 </script>
DOM相关-2: <style> #test{width:300px;height:300px;background:blue;} </style> <body> <div id="test"></div> <script type="text/javascript"> var test = document.getElementById("test"); if(document.all){ test.style.filter = ‘alpha(opacity=20)’;// IE }else{ test.style.opacity = 0.2;// firefox } </script>
Event相关-1: <input type="button" value="click me" id="btn" /> <span id="span">hello world</span> <script type="text/javascript"> document.getElementById("btn").onclick = function(e){ e = window.event || e; var el = e.srcElement || e.target; alert(el.tagName); } document.getElementById("span").onclick = function(e){ e = window.event || e; var el = e.srcElement || e.target; alert(el.tagName); } </script>
Event相关-2: <input type="button" value="click me" id="btn" /> <script type="text/javascript"> var btn = document.getElementById("btn"); if(document.all){ // IE btn.attachEvent("onclick",function(){ alert("hello world"); }); } else { // firefox btn.addEventListener("click",function(){ alert("hello world"); },false); } </script>
其它操作: // 设置cookie document.cookie = "name=adang; expires= Mon, 04 Oct 2010 02:40:14 GMT; path=/"; document.cookie = "sex=male; expires= Mon, 04 Oct 2010 02:40:14 GMT; path=/"; document.cookie = "blog=http://www.adanghome.com; expires= Mon, 04 Oct 2010 02:40:14 GMT; path=/"; /* 读取cookie ** 此时cookie里的值为"name=adang; sex=male; blog=http://www.adanghome.com" */ var cookieStr = document.cookie; // 对字符进行操作,取出name对应的值 var name = cookieStr.split("name")[1].split(";")[0].split("=")[1]; alert(name);
原生javascript写程序就像汽车行驶在一条凹凸不平的小路上。原生javascript写程序就像汽车行驶在一条凹凸不平的小路上。
控制全局作用域的变量数量: <input type="button" value="click me" id="btn" /> <script type="text/javascript"> (function(){ var a = 1,btn = document.getElementById("btn"); btn.onclick = function(){ a++; alert(a); } })(); </script> ... <script type="text/javascript"> (function(){ var a = 100; })(); </script>
问题一:匿名函数间无法通信 问题二:如果匿名函数内容很长 ,函数内部还是有冲突隐患
命名空间 <script type="text/javascript"> var GLOBAL = {}; GLOBAL.namespace = function(str){ var arr = str.split("."),o = GLOBAL; 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(){ GLOBAL.namespace("A"); GLOBAL.A.a=1; var btn = document.getElementById("btn"); btn.onclick = function(){ GLOBAL.A.a++; alert(GLOBAL.A.a); } GLOBAL.namespace("B"); GLOBAL.B.a = 100; })(); </script> ... <script type="text/javascript"> (function(){ var a = 100; alert(a); alert(GLOBAL.A.a); })(); </script>
封装DOM的接口 <script type="text/javascript"> function getNextNode(node){ if(ie){ … } else { … } }; function setOpacity (node,opacityValue){ if(ie){ … } else { … } } </script>
封装Event的接口 <script type="text/javascript"> function getEventTarget(e){ if(ie){ … } else { … } }; function on (node,eventType,handler){ if(ie){ … } else { … } } </script>
将函数归到相应的命名空间下: <script type="text/javascript"> var GLOBAL = {}; GLOBAL.namespace = function(str){ … }; … // GLOBAL.extend、GLOBAL.merge GLOBAL.namespace(“Dom”); GLOBAL.Dom.getNextSibling = function(){ … } GLOBAL.Dom.setOpacity = function(){ … } … // GLOBAL.Dom.getPrevSibling、GLOBAL.Dom.getStyle GLOBAL.namespace(“Event”); GLOBAL.Event.getEventTarget = function(){ … } GLOBAL.Event.on = function(){ … } … // GLOBAL.Event. stopPropagation 、GLOBAL.Event.getXY </script>
将DOM、Event相关的操作进行封装,另外扩展一些原生javascript语言层面不提供的接口,组成新的底层。将DOM、Event相关的操作进行封装,另外扩展一些原生javascript语言层面不提供的接口,组成新的底层。
底层替我们铲平了路面的凸起(浏览器差异),填补了路面的凹底层替我们铲平了路面的凸起(浏览器差异),填补了路面的凹 陷(补充javascript语言的底层方法)
封装cookie的接口 <script type="text/javascript"> var cookie = { set : function(){ … }, read : function(){ … }, del : function(){ } }; </script>
将函数归到相应的命名空间下: <script type="text/javascript"> GLOBAL.namespace(“Cookie”); GLOBAL.Cookie = { set : function(){ …} read : function(){ … } del : function(){ … } } … // GLOBAL.Ajax、GLOBAL.Drag、GLOBAL.Resize… </script>
将常见功能封装成组件,组件将内部实现细节透明,提供简单易用的接口。将常见功能封装成组件,组件将内部实现细节透明,提供简单易用的接口。
组件层替我们在路面铺上沥青,将普通小路变成高速公路。组件层替我们在路面铺上沥青,将普通小路变成高速公路。
应用层:和页面具体需求相关,调用底层的底层接口和组件层的组件,依赖底层和组件层。应用层:和页面具体需求相关,调用底层的底层接口和组件层的组件,依赖底层和组件层。 组件层:调用底层提供的接口,封装常用组件,依赖底层。和具体功能有关,但和页面需求无关。为应用层提供组件(组件提供组件的接口)。例如Drag、Cookie、Ajax、Resize、Tab、Tree。 底层 :封装DOM、Event在各浏览器下的区别,提供统一的接口;扩展javascript语言,提供全局性的方法。和具体功能无关,只为组件层和应用层提供底层接口。例如getNextSibling()、getEventTarget()、namespace()、trim()、isArray()。
典型的引用方法: <html> <head> <title>阿当制作</title> </head> <body> <script type = “ text/javascript ” src = “ base.js ”></script> <!-- 底层 --> <script type = “ text/javascript ” src = “ ajax.js ”></script> <!– 组件层 --> <script type = “ text/javascript ” src = “ tab.js ”></script> <!-- 组件层 --> <script type = “ text/javascript ”> <!-- 应用层 --> (function(){ // your code here })(); </script> </body> </html>
应用层:1) 避免多人合作的冲突; 2) 组件间的依赖关系处理; 组件层:1) 尽可能丰富的组件; 2) 易用性; 3) 可重用性。 底层 :1) 跨浏览器兼容,屏蔽尽可能多的浏览器差异; 2) 补充完善javascript语言本身的不足; 3) 精简。
框架可以帮助我们将精力集中在应用层的逻辑处理上,例如设计类、接口、设计模式,而不是将精力放在频繁的底层操作上。框架可以帮助我们将精力集中在应用层的逻辑处理上,例如设计类、接口、设计模式,而不是将精力放在频繁的底层操作上。 例:http://www.adanghome.com/js_demo/1/
开发框架的难点:代码品质、组件的丰富程度、兼容性、易用性、可复用性…开发框架的难点:代码品质、组件的丰富程度、兼容性、易用性、可复用性…
我们有大量开源框架可以选择:jQuery、YUI、 Dojo、 Prototype、mootool…
“小”与“强”的平衡: YUI2将文件分成粒度非常小,靠loader机制按需加载,达到“小”和“强”的平衡,扩展性好; jQuery靠作者强大的个人能力,将js编程发挥到极致,达到“小”和“强”的平衡,扩展性差。
处理依赖关系: YUI2通过loader动态加载样式和脚本,智能地完成依赖关系的处理,调用简单,不易出错; jQuery使用传统方式,手动添加样式和脚本,易出错。
第三方组件: YUI2所有组件都是官方提供,第三方组件少,但代码品质高。 jQuery有大量第三方组件,但代码品质参差不齐。
实际工作情况: 应用层:调用下面三层 自定义组件层:我们提供,定制型 框架组件层:框架提供,通用型 底层 :框架提供,通用型
存在的问题: 1)如何处理多人合作的问题; 2)自定义类的格式。
类库?框架? 类库提供预编写好的类,隐藏底层操作,简化开发。帮助工程师将精力集中在应用层。 框架提供整套解决方案,除类库之外,还包括应用层的格式和自定义组件的格式。进一步帮助工程师将精力从“格式”中解放出来,专注于“逻辑”处理。
widget init() destroy() render(){ renderUI(); bindUI(); syncUI(); } MyWidget.HTML_PARSER = { } 例:http://www.adanghome.com/js_demo/2/
YUI3带来的分层: 应用层:如有自定义类,继承抽象类 自定义组件层:我们提供,继承自抽象类 框架组件层:框架提供,继承自抽象类 抽象类层:框架提供, 统一自定义类的格式 底层:框架提供