Prototype Study (转)

什么是Prototype

Prototype 是由 Sam Stephenson 开发的一个 Javascript 类库,也是其他框架的鼻祖。其对现有的部分 Javascript 对象比如 Object 、 Function 、 Dom 、 String 等进行扩展,并且对 Ajax 应用进行封装,借此提供了兼容标准的更加易于使用的类库,极大的方便开发人员快速创建具备高度交互性的 Web2.0 胖客户端应用程序。

(相关站点:http://www.prototypejs.org/ )

Prototype 最初的目标是应用于 Ruby 领域的,不过由于优秀的表现和完美的封装以及服务器语言无关性,现在已经被应用到各个领域,包括 Java 、 .NET 、 PHP 等。不过在 Prototype 的源码中,还是可以找到 Ruby 的影子,比如 Ruby 样式的 Array 对象枚举。

正如之前提到的, Prototype 是一个底层的远程调用包,虽然其仅仅是一个千余行的 Javascript 文件,但是它为其他框架提供了最底层的 Javascript 扩展和 Ajax 封装。其他 Javascript 程序库在其基础上构建了更加高级的功能和 UI 效果,比如 Script.aculo.us 。

Prototype 目前的最新版本是1.5 ,其官方网站提供了最新版本的下载,包括 zip 包、 js 文件和 Subvision 源码。不过和其他版本一样, Prototype 官方网站并未提供完整的参考文档,开发者只能通过阅读源码掌握其功能。可喜的是,网上已经流传着不少关于 Prototype 源码解读和使用的文档,这在一定程度上弥补了 Prototype 官方文档不足的遗憾。


2.2 软件组织架构以及应用

Prototype 主要包括三个内容:
一是提供了一些全局性的函数,替代原先烦琐重复的代码;二是对现有 Javascript 、 DOM 对象的扩展,提供访问公共函数的捷径;三是对 Ajax 应用的封装,使得开发 Ajax 应用更加容易和快速。

全局性的函数,比较有代表性的 $ 系列函数和 Try.these() 函数。

$() 函数是用于替代在 DOM 中频繁使用的 document.getElementById() 方法的,其返回参数传入的 id 所指向的元素。不过,其允许传入多个 id 作为参数,然后返回一个其 id 指向的元素的 Array 对象。

$F() 函数则用于返回任何表单输入控件的值,比如文本框、文本区域、下拉列表,其也是以元素的 id 或者元素本身作为参数。不过,必须注意的是, id 所指向的元素必须支持 value 属性,比如文本框。如果 id 指向一个按钮,那自然就得不到所要的 value 值。

$A() 函数能够将其接受到的任何可枚举列表转化成为一个 Array 对象,比如将 string 字符串转化成 Array 数组。 $H() 函数则将传入的对象转换成一个可枚举的和联合数组类似的 Hash 对象。 $R() 函数是 new ObjectRange(lowBound, upperBound, excludeBounds) 的缩写和替代。

Try.thiese() 方法以一系列的函数作为参数,按照顺序一个一个的执行,返回第一个成功执行的函数的返回值。这使得想调用不同的方法直到其中一个成功执行的需求变得容易和 直观。否则我们就得变通的用 if else 去判断了。典型的比如在保证浏览器兼容的情况下实例化 XHR 对象。

Prototype 对 Javascript 的 Object 、 Number 、 Function 、 String 、 Array 、 Event 等对象进行了扩展,创建了一些新的对象和类,并在此基础上提供了很多有用的公共函数,比如 each() 、 any() 、 collect() 等。

Prototype 另外一个值得称道的是对 Ajax 的封装和简化,这也是 Prototype 吸引我们的另外一个重要之处。 Prototype 的 Ajax 功能主要由 Ajax.Request 和 Ajax.Updater 两个类完成。

在没有使用 Prototype 之前,我们需要创建 XHR 对象实例并且异步的跟踪其进程,在回调函数中使用 DOM 解析其返回的响应数据并且处理后更新页面。而 Ajax.Request 类提供了完成这一系列步骤的捷径。我们只需要将目标 URL 、 URL 参数、 http 请求方法类型、回调函数名称等一股脑的传递给 Ajax.Request 类即可。

Ajax.Request 类是针对需要解析服务器返回的响应数据的情况。而如果服务器返回的信息已经是 HTML 格式,只需要填充到某个 HTML 控件中,则可以使用 Ajax.Updater 类。其调用 innerHTML 直接将 HTML 代码填充到指定的 HTML 控件内部。

难得可贵的是,以往我们需要判断 XHR 的 readyState 和 status 值来获取 http 请求的状态并且作出相应的处理,以便应付请求失败的情况;而 AjaxRequest 和 Ajax.Updater 类提供了 onComplete 来替代这些烦琐的判断,其只需要简单的在请求的选项参数中的名为 onXXXX 属性 / 方法中提供自定义的方法对象即可。

接下来,我们使用 Prototype1.4 ,列举一二,体验一下 Prototype 的主要功能及其所带来的便捷。

2.3 循序渐近

从 Prototype 官方网站 http://prototype.conio.net/ 下载最新的开发包 prototype-1.4.0.js ,放到应用程序目录中,通过 <script> 代码引入 Prototype 程序库:

XML/HTML代码
  1. < script   language = "javascript"   type = "text/javascript"   src = "prototype-1.4.0.js" > </ script >   

 

2.3.1 $ 系列函数体验

在 Prototype 出现之前,我们使用这种方式定位页面上的某个 HTML 元素及其值:

JavaScript代码
  1. var  myElement = document.getElementById(“your element 's id”);  
  2. var myValue = document.getElementById(“your element' s id”).value;  


现在,可以分别使用 $() 函数和 $F() 函数来代替,例程 1 展示 $() 和 $F() 函数的用法:

JavaScript代码
  1. var  myElement = $(“your element 's id”);  
  2. var myValue = $F(“your element' s id”);  

 

例程 1 : $() 和 $F() 函数的用法

XML/HTML代码
  1. < p > Username: < input   type = "text"   name = "txtUsername"   value = "Jimmy" > </ p >   
  2. < p >   
  3. < input   type = "button"   name = "$Test"   value = " $ "   onClick = "window.alert($('txtUsername'))" >     
  4. < input   type = "button"   name = "$FTest"   value = " $F "   onClick = "window.alert($F('txtUsername'))" >     
  5. </ p >   


$A() 函数则将其接收到的可枚举的任何参数转化成为一个 Array 对象。结合 Prototype 对 Array 的扩展, $A() 能够提供更加强大的功能。例程 2 使用 $A() 函数获取页面中的全部 input 类型的控件,并使用扩展后的 each() 函数遍历全部的控件。

例程 2 : $A() 函数的用法

XML/HTML代码
  1. < script   language = "javascript"   type = "text/javascript" >     
  2. /*$A 函数体验 */    
  3. function do$ATest() {   
  4.     var  nodeList  =  document .getElementsByTagName("input");   
  5.     var  nodeArray  = $A(nodeList);   
  6.     var  message  =  " 全部 input 控件: " ;   
  7.   
  8.     nodeArray.each(    
  9.         function(node) {    
  10.             message += node.type + "|" + node.name + "|" + node.value + "";    
  11.         }    
  12.     );    
  13.     window.alert(message);    
  14. }   
  15. </ script >     
  16. < input   type = "button"   name = "$ATest"   value = " $A "   onClick = "do$ATest()" >   

 

2.3.2 Try.these() 函数的妙用
我们知道, XHR 是 Ajax 的核心之一。但是各个浏览器对 XHR 的实现不同, IE 浏览器的各个版本对 XHR 的支持也有所差异。为了保证 Ajax 的浏览器兼容性,在实例化 XHR 对象的时候,通常要使用 try/catch 对兼容性进行判断。比如例程 3 所示。

例程 3 :使用 try/catch 块实例化 XHR

JavaScript代码
  1. var  xhr =  null ;    
  2. if (window.XMLHttpRequest) {    
  3.     xhr =  new  XMLHttpRequest();    
  4.      if (xhr.overrideMimeType)   
  5.         xhr.overrideMimeType(“text/xml”);    
  6.     }  else   if  (window.ActiveXObject) {    
  7.          try  {    
  8.             xhr =  new  ActiveXObject(“Msxml2.XMLHTTP”);    
  9.         }  catch (e) {    
  10.              try  {    
  11.                 xhr =  new  ActiveXObject(“Microsoft.XMLHTTP”);    
  12.             } catch (e) {}    
  13.         }    
  14. }  

 

而现在,使用 Try.these() 函数,这些烦琐的过程变得异常简单。

例程 4 :使用 Try.these() 函数实例化 XHR

JavaScript代码
  1. function  doInitialXHR() {   
  2.      return  Try.these(   
  3.          function () { return   new  ActiveXObject( 'Msxml2.XMLHTTP' )},   
  4.          function () { return   new  ActiveXObject( 'Microsoft.XMLHTTP' )},
  5.          function () { return   new  XMLHttpRequest()}   
  6.         ) ||  false ;   
  7. }  


2.3.3 对集合类的遍历

之前提过, Prototype 最初的应用领域是 Ruby 。 Ruby 为遍历集合中的元素提供了一系列快捷的方法,使得执行维护、查找、收集、删除其中的元素更加快速。 Prototype 新建了一个 Enumerable 对象,为 Javascript 提供类似 Ruby 的功能。

在 Ruby 、 .NET 语言中,都支持使用 each 关键词对集合中的元素进行遍历。在 Enumberable 对象中,还有很多方法比如 all() 、 any() 、 collect() 等都是基于 each() 方法实现的。所以, each() 方法是操作集合元素的基础。

each() 方法使用 iterator 依次获取集合中的每个元素,并将其作为匿名函数的参数;也可以在该匿名函数中加上可选参数 index ,获取当前元素的索引值。其实在例程 2 中,我们已经使用了 each() 方法。

例程 5 使用 each() 方法,对一个保存货物价格的数组进行遍历,显示价格及其索引值。

例程 5 :使用 each() 方法遍历集合

JavaScript代码
  1. function  doEachTest() {   
  2.      var  prices = [100.2, 445, 552.3, 56.0];   
  3.     prices.each(   
  4.          function (price, index) {   
  5.             window.alert( "Value:"  + price +  "| Index:"  + index);   
  6.         }   
  7.     );   
  8. }  

 

2.3.4 Prototype 的Ajax体验

Prototype 将 Ajax 应用封装为 Ajax.Request 和 Ajax.Update 类。使用这两个类,可以应付大部分的 Ajax 应用,而且不需要烦琐的实例化 XHR 、监控请求状态的过程。

假设我们将书籍的信息保存在一个 XML 文档中,如例程 6 所示。

例程 6 :保存书籍信息的 XML 文档

XML/HTML代码
  1. <? xml   version = "1.0"   encoding = "gb2312" ?>   
  2. < books >   
  3. < book >   
  4.      < title > Ajax bible </ title >   
  5.      < pages > 500 </ pages >   
  6. </ book >   
  7. < book >   
  8.      < title > Build with Ant </ title >   
  9.      < pages > 632 </ pages >   
  10. </ book >   
  11. < book >   
  12.      < title > Google </ title >   
  13.      < pages > 934 </ pages >     
  14. </ book >   
  15. </ books >   

 

现在,我们使用 Ajax.Request 类去获取这个 XML 文档的内容,并将其显示出来。例程 7 展示了这一过程。

例程 7 :使用 Ajax.Request 获取 XML 文档内容

XML/HTML代码
  1. < script   language =”javascript”  type =”text/javascript” >   
  2. /*Ajax.Request 类体验 */   
  3. function doAjaxRequest() {   
  4.     var  url  =  "books.xml" ;   
  5.     var  myAjax  =  new  Ajax.Request(url, {   
  6.         method:"get",   
  7.         onComplete:showResponse   
  8.     }   
  9. );   
  10. }   
  11. /*Ajax.Request 类回调函数 */    
  12. function showResponse(request) {    
  13.     window.alert(request.responseText);    
  14. }   
  15. </ script >     
  16. < input   type = "button"   name = "ajaxRequest"   value = "ajaxRequest"   onClick = "doAjaxRequest()" >   

 

图 1 展示了使用 Ajax.Request 后所获取的 books.xml 文档内容。
大小: 49.43 K 尺寸: 285 x 289 浏览: 23 次 点击打开新窗口浏览全图
图 1 使用 Ajax.Request 后所获取的 books.xml 文档内容

例程 7 中, onComplete 指定的 showResponse 函数其实是 Ajax 的回调函数,通常在这个回调函数中完成对响应数据的解析和显示。而如果服务器端返回的是已经格式化后的 HTML 代码(这点在 Ruby 中很流行),则可以使用 Ajax.Updater 。例程 8 使用 Ajax.Updater 将服务器的响应数据填充到指定的 div 中。图 2 展示了使用 Ajax.Updater 的执行效果。

例程 8 :使用 Ajax.Updater 获取服务器的响应数据

XML/HTML代码
  1. < script   language =”javascript”  type =”text/javascript” >     
  2. /*Ajax.Update 类体验 */    
  3. function doAjaxUpdate() {   
  4.     var  url  =  "response.php" ;   
  5.     var  pars  =  "field=all&show=true" ;   
  6.     var  myAjax  =  new  Ajax.Updater("divContent", url,
  7.         {   
  8.             method:"get",   
  9.             parameters:pars   
  10.         }   
  11.     );
  12. }   
  13. </ script >     
  14. < input   type = "button"   name = "ajaxUpdate"   value = "ajaxUpdate"   onClick = "doAjaxUpdate()" >     
  15. < p > < div   id = "divContent" > </ div > </ p >    

大小: 5.89 K 尺寸: 125 x 81 浏览: 72 次 点击打开新窗口浏览全图
图 2 使用 Ajax.Updater 的执行效果

例程 9 是例程 8 所请求的 PHP 文件,其简单的打印出加粗后的“ Ajax.Update ”字样。

PHP代码
  1. <?php   
  2. echo   '<strong>Ajax.Update</strong>' ;   
  3. ?> 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值