prototype 1.5相关知识及他人笔记


Posted in Javascript onDecember 16, 2006

一直没有没有时间看prototype,现在好了,已经更新到了1.5 pre1,呵呵,强大的功能不得不学习啊,这个是提升自己JS能力的又一个捷径.

1. Prototype是什么?
或许你还没有用过它, prototype.js 是一个由Sam Stephenson写的JavaScript包。这个构思奇妙编写良好的一段兼容标准的一段代码将承担创造胖客户端, 高交互性WEB应用程序的重担。轻松加入Web 2.0特性。

如果你最近体验了这个程序包,你很可能会发现文档并不是它的强项之一。像所有在我之前的开发者一样,我只能一头扎进prototype.js的源代码中并且试验其中的每一个部分。 我想当我学习他的时候记写笔记然后分享给其他人将会很不错。

我也一起提供了这个包的对象,类,方法和扩展的 非官方参考 。

2. 通用性方法
这个程序包里面包含了许多预定义的对象和通用性方法。编写这些方法的明显的目的就是为了减少你大量的重复编码和惯用法。

从Prototype1.5.x版本开始,你可以更方便的如下面代码一样操作DOM对象了: 

程序代码

var ele = $("myelement");
ele.hide(); //隐藏DOM对象对比从前的版本var ele = $("myelement");
Element.hide(ele); //隐藏DOM对象

这样的改变有什么益处呢? 我觉得一来是更面向对象了,二来就是便于将来IDE里的代码提示。 

2.1. 使用 $()方法
$() 方法是在DOM中使用过于频繁的 document.getElementById() 方法的一个便利的简写,就像这个DOM方法一样,这个方法返回参数传入的id的那个元素。

比起DOM中的方法,这个更胜一筹。你可以传入多个id作为参数然后 $() 返回一个带有所有要求的元素的一个 Array 对象。下面的例子会向你描述这些。

程序代码

<HTML>
<HEAD>
<TITLE> Test Page </TITLE>
<script src="prototype-1.3.1.js"></script>

<script>
function test1()
{
var d = $('myDiv');
alert(d.innerHTML);
}

function test2()
{
var divs = $('myDiv','myOtherDiv');
for(i=0; i<divs.length; i++)
{
alert(divs.innerHTML);
}
}
</script>
</HEAD>

<BODY>
<div id="myDiv">
<p>This is a paragraph</p>
</div>
<div id="myOtherDiv">
<p>This is another paragraph</p>
</div>

<input type="button" value=Test1 onclick="test1();"><br>
<input type="button" value=Test2 onclick="test2();"><br>

</BODY>
</HTML>

这个方法的另一个好处就是你可以传入id字符串或者元素对象自己,这使得在创建可以传入任何形式参数的方法的时候, 它变得非常有用。

2.2. 使用$F()方法
$F()方法是另一个非常受欢迎的简写。它可以返回任何输入表单控件的值,如文本框或下拉框。 这个方法可以传入元素的id或者元素自己。

程序代码

<script>
function test3()
{
alert( $F('userName') );
}
</script>

<input type="text" id="userName" value="Joe Doe"><br> 
<input type="button" value=Test3 onclick="test3();"><br>

2.3. 使用Try.these()方法
Try.these() 方法使得实现当你想调用不同的方法直到其中的一个成功正常的这种需求变得非常容易, 他把一系列的方法作为参数并且按顺序的一个一个的执行这些方法直到其中的一个成功执行,返回成功执行的那个方法的返回值。

在下面的例子中, xmlNode.text在一些浏览器中好用,但是xmlNode.textContent在另一些浏览器中正常工作。 使用Try.these()方法我们可以得到正常工作的那个方法的返回值。

程序代码

<script>
function getXmlNodeValue(xmlNode){
return Try.these(
function() {return xmlNode.text;},
function() {return xmlNode.textContent;)
);
}
</script>

3. Ajax 对象
上面提到的共通方法非常好,但是面对它吧,它们不是最高级的那类东西。它们是吗?你很可能自己编写了这些甚至在你的脚本里面有类似功能的方法。但是这些方法只是冰山一角。

我很肯定你对prototype.js感兴趣的原因很可能是由于它的AJAX能力。所以让我们解释当你需要完成AJAX逻辑的时候,这个包如何让它更容易。

Ajax 对象是一个预定义对象,由这个包创建,为了封装和简化编写AJAX 功能涉及的狡猾的代码。 这个对象包含一系列的封装AJAX逻辑的类。我们来看看它们的一些。

3.1. 使用 Ajax.Request类
如果你不使用任何的帮助程序包,你很可能编写了整个大量的代码来创建XMLHttpRequest对象并且异步的跟踪它的进程, 然后解析出响应 然后处理它。当你不需要支持多于一种类型的浏览器时你会感到非常的幸运。

为了支持 AJAX 功能。这个包定义了 Ajax.Request 类。

假如你有一个应用程序可以通过url http://yoursever/app/get_sales?empID=1234&year=1998与服务器通信。它返回下面这样的XML 响应。

程序代码

<?xml version="1.0" encoding="utf-8" ?>
<ajax-response>
<response type="object" id="productDetails">
<monthly-sales>
<employee-sales>
<employee-id>1234</employee-id>
<year-month>1998-01</year-month>
<sales>$8,115.36</sales>
</employee-sales>
<employee-sales>
<employee-id>1234</employee-id>
<year-month>1998-02</year-month>
<sales>$11,147.51</sales>
</employee-sales>
</monthly-sales>
</response>
</ajax-response>

用 Ajax.Request对象和服务器通信并且得到这段XML是非常简单的。下面的例子演示了它是如何完成的。

程序代码

<script>
function searchSales()
{
var empID = $F('lstEmployees');
var y = $F('lstYears');
var url = 'http://yoursever/app/get_sales';
var pars = 'empID=' + empID + '&year=' + y;
var myAjax = new Ajax.Request(
url,
{method: 'get', parameters: pars, onComplete: showResponse}
);

}

function showResponse(originalRequest)
{
//put returned XML in the textarea
$('result').value = originalRequest.responseText;
}
</script>

<select id="lstEmployees" size="10" onchange="searchSales()">
<option value="5">Buchanan, Steven</option>
<option value="8">Callahan, Laura</option>
<option value="1">Davolio, Nancy</option>
</select>
<select id="lstYears" size="3" onchange="searchSales()">
<option selected="selected" value="1996">1996</option>
<option value="1997">1997</option>
<option value="1998">1998</option>
</select>
<br><textarea id=result cols=60 rows=10 ></textarea>

你看到传入 Ajax.Request构造方法的第二个对象了吗? 参数{method: 'get', parameters: pars, onComplete: showResponse} 表示一个匿名对象的真实写法。他表示你传入的这个对象有一个名为 method 值为 'get'的属性,另一个属性名为 parameters 包含HTTP请求的查询字符串,和一个onComplete 属性/方法包含函数showResponse。

还有一些其它的属性可以在这个对象里面定义和设置,如 asynchronous,可以为true 或 false 来决定AJAX对服务器的调用是否是异步的(默认值是 true)。

这个参数定义AJAX调用的选项。在我们的例子中,在第一个参数通过HTTP GET命令请求那个url,传入了变量 pars包含的查询字符串, Ajax.Request 对象在它完成接收响应的时候将调用showResponse 方法。

也许你知道, XMLHttpRequest在HTTP请求期间将报告进度情况。这个进度被描述为四个不同阶段:Loading, Loaded, Interactive, 或 Complete。你可以使 Ajax.Request 对象在任何阶段调用自定义方法 ,Complete 是最常用的一个。想调用自定义的方法只需要简单的在请求的选项参数中的名为 onXXXXX 属性/方法中提供自定义的方法对象。 就像我们例子中的 onComplete 。你传入的方法将会被用一个参数调用,这个参数是 XMLHttpRequest 对象自己。你将会用这个对象去得到返回的数据并且或许检查包含有在这次调用中的HTTP结果代码的 status 属性。

还有另外两个有用的选项用来处理结果。我们可以在onSuccess 选项处传入一个方法,当AJAX无误的执行完后调用, 相反的,也可以在onFailure选项处传入一个方法,当服务器端出现错误时调用。正如onXXXXX 选项传入的方法一样,这两个在被调用的时候也传入一个带有AJAX请求的XMLHttpRequest对象。

我们的例子没有用任何有趣的方式处理这个 XML响应, 我们只是把这段XML放进了一个文本域里面。对这个响应的一个典型的应用很可能就是找到其中的想要的信息,然后更新页面中的某些元素, 或者甚至可能做某些XSLT转换而在页面中产生一些HTML。

3.2. 使用 Ajax.Updater 类
如果你的服务器的另一端返回的信息已经是HTML了,那么使用这个程序包中 Ajax.Updater 类将使你的生活变得更加得容易。用它你只需提供哪一个元素需要被AJAX请求返回的HTML填充就可以了,例子比我写说明的更清楚。

程序代码

<script>
function getHTML()
{
var url = 'http://yourserver/app/getSomeHTML';
var pars = 'someParameter=ABC';

var myAjax = new Ajax.Updater('placeholder', url, {method: 'get', parameters: pars});

}
</script>

<input type=button value=GetHtml onclick="getHTML()">
<div id="placeholder"></div>

你可以看到,这段代码比前面的例子更加简洁,不包括 onComplete 方法,但是在构造方法中传入了一个元素id。 我们来稍稍修改一下代码来描述如何在客户端处理服务器段错误成为可能。

我们将加入更多的选项, 指定处理错误的一个方法。这个是用 onFailure 选项来完成的。

我们也指定了一个 placeholder 只有在成功请求之后才会被填充。为了完成这个目的我们修改了第一个参数从一个简单的元素id到一个带有两个属性的对象, success (一切OK的时候被用到) 和 failure (有地方出问题的时候被用到) 在下面的例子中没有用到failure属性,而仅仅在 onFailure 处使用了 reportError 方法。

程序代码

<script>
function getHTML()
{
var url = 'http://yourserver/app/getSomeHTML';
var pars = 'someParameter=ABC';
var myAjax = new Ajax.Updater(
{success: 'placeholder'},
url,
{method: 'get', parameters: pars, onFailure: reportError});

}

function reportError(request)
{
alert('Sorry. There was an error.');
}
</script>

<input type=button value=GetHtml onclick="getHTML()">
<div id="placeholder"></div>

如果你的服务器逻辑是返回JavaScript 代码而不是单纯的 HTML 标记, Ajax.Updater对象可以执行那段JavaScript代码。为了使这个对象对待响应为JavaScript,你只需在最后参数的对象构造方法中简单加入evalScripts: true属性。
最近做otalk,开始是基于prototype1.4的,后来因为我加上了scriptaculous 1.6.1,她要求prototype的版本是1.5的,所以就升级到了1.5,看着demo学习起了scriptaculous的用法. 
用法稍后整理,因为在使用过程中很多次效果都不让自己满意,想看代码又看不明白,经过一次折磨,我下定决心,一定要把scriptaculous和prototype的代码看明白! 
这里作为我的学习笔记,可能没有什么顺序了逻辑,等到学习完,最后整理 
首先是定义类  看着笑笑老师的一些介绍,自己看是试验起来,往往很多东西看了觉着明白,其实还是差很多的 
var Class = { 
  create: function() { 
    return function() { 
      this.initialize.apply(this, arguments); 
    } 
  } 

定义了一个class函数作为创建类的模版或者说是原型 
使用方法 
var llinzzi= Class.create(); 
llinzzi.prototype = { 
    initialize:function(){ 
          document.write('实例被创建'); 
    }, 
    fun1:function(){document.write('方法被实例调用');} 

var linChild = new llinzzi(); 
运行,输出'实例被创建'说明initialize是创建实例的时候被调用的 
回顾 Class代码中 
    return function() { 
      this.initialize.apply(this, arguments); 
    } 
看出,当执行create方法时,就开始调用. 
linChild.fun1(); 
输出'方法被实例调用',fun1方法被成功调用 
就是当采用了prototype的Class.create();方法创建对象的时候,initialize作为特殊的方法,在创建实例的时候被执行,用以初始化. 
续承 
Object.extend = function(destination, source) { 
  for (var property in source) { 
    destination[property] = source[property]; 
  } 
  return destination; 

用法 
Object.extend(目标,源); 
让我产生奇怪的是scriptaculous中的一段代码 
    var options = Object.extend({ 
      greedy:     true, 
      hoverclass: null, 
      tree:       false 
    }, arguments[1] || {}); 
既然是定义一个options为什么还要用Object.extend方法 
直接 
var options ={ 
      greedy:     true, 
      hoverclass: null, 
      tree:       false 

不就行了么?等等,出现问题了.后面还有arguments[1] || {},这应该是目标,目标是函数的参数,分析下,获取参数,如果没有这个参数的时候则为{}就是恐,如果有的话,相比也是{hoverclass:'xx'}的格式,哦,原来定义options也不是这么简单的,先看有没有参数,无论有没有,利用Object.extend方法,把参数中的对象追加或覆盖到前面的{     greedy:     true,      hoverclass: null,      tree:       false}中,如果参数是无,则相当简单的上面的 var options = {};了但,如果参数中有{hoverclass:'abc'}呢?这时候覆盖了原来的hoverclass的值null,然后看Object.extend方法返回值就是第一个参数被覆盖后的全部的值 
不得不佩服,一段一句进行定义,同时有设置了默认值. 
越看越有意思,继续看下去

Javascript 相关文章推荐
教您去掉ie网页加载进度条的方法
Dec 09 Javascript
jquery获取checkbox的值并post提交
Jan 14 Javascript
jquery任意位置浮动固定层插件用法实例
May 29 Javascript
jQuery如何封装输入框插件
Aug 19 Javascript
js严格模式总结(分享)
Aug 22 Javascript
JavaScript常用代码书写规范的超全面总结
Sep 11 Javascript
D3.js实现折线图的方法详解
Sep 21 Javascript
利用JavaScript在网页实现八数码启发式A*算法动画效果
Apr 16 Javascript
解决vue-router进行build无法正常显示路由页面的问题
Mar 06 Javascript
vue+webpack模拟后台数据的示例代码
Jul 26 Javascript
js布局实现单选按钮控件
Jan 17 Javascript
js实现磁性吸附的示例
Oct 26 Javascript
飞鱼(shqlsl) javascript作品集
Dec 16 #Javascript
XHTML-Strict 内允许出现的标签
Dec 11 #Javascript
JS的IE和Firefox兼容性集锦
Dec 11 #Javascript
不错的新闻标题颜色效果
Dec 10 #Javascript
用脚本调用样式的几种方法
Dec 09 #Javascript
用js计算页面执行时间的函数
Dec 07 #Javascript
JS获取IUSR_机器名和IWAM_机器名帐号的密码
Dec 06 #Javascript
You might like
PHP性能优化准备篇图解PEAR安装
2011/12/05 PHP
php调用dll的实例操作动画与代码分享
2012/08/14 PHP
解析PHP中intval()等int转换时的意外异常情况
2013/06/21 PHP
PHP的mysqli_query参数MYSQLI_STORE_RESULT和MYSQLI_USE_RESULT的区别
2014/09/29 PHP
php基于str_pad实现卡号不足位数自动补0的方法
2014/11/12 PHP
PHP类的自动加载机制实现方法分析
2019/01/10 PHP
Laravel框架源码解析之反射的使用详解
2020/05/14 PHP
有道JavaScript监听浏览器的问题
2010/06/23 Javascript
利用毫秒减值计算时长的js代码
2013/09/22 Javascript
JavaScript如何动态创建table表格
2020/08/02 Javascript
ES6中Proxy代理用法实例浅析
2017/04/06 Javascript
ionic2自定义cordova插件开发以及使用(Android)
2017/06/19 Javascript
React组件refs的使用详解
2018/02/09 Javascript
Vue开发之watch监听数组、对象、变量操作分析
2019/04/25 Javascript
React精髓!一篇全概括小结(急速)
2019/05/23 Javascript
如何从头实现一个node.js的koa框架
2019/06/17 Javascript
用vue写一个日历
2020/11/02 Javascript
[53:10]2018DOTA2亚洲邀请赛 4.6 淘汰赛 VP vs VG 第一场
2018/04/11 DOTA
Python中删除文件的程序代码
2011/03/13 Python
python批量下载图片的三种方法
2013/04/22 Python
Python中的MongoDB基本操作:连接、查询实例
2015/02/13 Python
Python Numpy 数组的初始化和基本操作
2018/03/13 Python
pandas or sql计算前后两行数据间的增值方法
2018/04/20 Python
python和mysql交互操作实例详解【基于pymysql库】
2019/06/04 Python
Python实现Canny及Hough算法代码实例解析
2020/08/06 Python
利用Python pandas对Excel进行合并的方法示例
2020/11/04 Python
python中使用.py配置文件的方法详解
2020/11/23 Python
美国儿童玩具、装扮和玩偶商店:Magic Cabin
2018/09/02 全球购物
What's the difference between an interface and abstract class? (接口与抽象类有什么区别)
2012/10/29 面试题
工会主席岗位责任制
2014/02/11 职场文书
人力资源部门的主要职能
2014/02/22 职场文书
21岁生日感言
2014/02/27 职场文书
民主生活会主持词
2015/07/01 职场文书
Python中的np.argmin()和np.argmax()函数用法
2021/06/02 Python
Python 正则模块详情
2021/11/02 Python
MySQL 数据库 增删查改、克隆、外键 等操作
2022/05/11 MySQL