冰河の泥鱼的专栏

非学无以成才,非志无以成学.

转载 prototype.js开发笔记收藏

新一篇: 某培训机构的JAVA面试试题[2007.3.17] | 旧一篇: 在 Windows 2000/XP/2003 环境下轻松构建PHP Web服务器

 
prototype.js开发笔记
来源:http://java.net

Table of Contents
覆盖版本 1.3.1
Chapter 1. Programming Guide
1.1. Prototype是什么?
如果你最近体验了这个程序包,你很可能会发现文档并不是它的强项之一。像所有在我之前的开发者一样,我只能一头扎进prototype.js的源代码中并且试验其中的每一个部分。 我想当我学习他的时候记写笔记然后分享给其他人将会很不错。
我也一起提供了这个包的对象,类,方法和扩展的 非官方参考
1.2. 关联文章
1.3. 通用性方法
这个程序包里面包含了许多预定义的对象和通用性方法。编写这些方法的明显的目的就是为了减少你大量的重复编码和惯用法。
1.3.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[i].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字符串或者元素对象自己,这使得在创建可以传入任何形式参数的方法的时候,它变得非常有用。
1.3.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>
1.3.3使用$A()方法
$A()方法把接收到的参数转换成一个Array对象。
这个方法加上对Array类的扩展,可以很容易的转换或者复制任意的列举列表到Array对象, 一个被推荐使用的用法就是转换DOMNodeLists到一个普通的数组里,可以被更广泛高效的使用,看下面的例子。
<script>
 
    function showOptions(){
        var someNodeList = $('lstEmployees').getElementsByTagName('option');
        var nodes = $A(someNodeList);
 
        nodes.each(function(node){
                alert(node.nodeName + ': ' + node.innerHTML);
            });
    }
</script>
 
<select id="lstEmployees" size="10" >
    <option value="5">Buchanan, Steven</option>
    <option value="8">Callahan, Laura</option>
    <option value="1">Davolio, Nancy</option>
</select>
 
<input type="button" value="Show the options" onclick="showOptions();" >
1.3.4使用$H()方法
$H()方法把对象转化成可枚举的貌似联合数组Hash对象。
<script>
    function testHash()
    {
        //let's create the object
        var a = {
            first: 10,
            second: 20,
            third: 30
            };
 
        //now transform it into a hash
       var h = $H(a);
        alert(h.toQueryString()); //displays: first=10&second=20&third=30
    }
 
</script>
1.3.5使用$R()方法
$R()方法是new ObjectRange(lowerBound, upperBound, excludeBounds)的一个简单快捷的使用方式。
ObjectRange类文档里面有完整的解释。 同时,我们来看看一个简单的例子, 来演示通过each方法遍历的用法。 那个方法的更多解释在Enumerable对象文档里面。
<script>
    function demoDollar_R(){
        var range = $R(10, 20, false);
        range.each(function(value, index){
            alert(value);
        });
    }
 
</script>
 
<input type="button" value="Sample Count" onclick="demoDollar_R();" >
1.3.6使用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>
1.4. Ajax对象
上面提到的共通方法非常好,但是面对它吧,它们不是最高级的那类东西。它们是吗?你很可能自己编写了这些甚至在你的脚本里面有类似功能的方法。但是这些方法只是冰山一角。
我很肯定你对prototype.js感兴趣的原因很可能是由于它的AJAX能力。所以让我们解释当你需要完成AJAX逻辑的时候,这个包如何让它更容易。
Ajax对象是一个预定义对象,由这个包创建,为了封装和简化编写AJAX功能涉及的狡猾的代码。 这个对象包含一系列的封装AJAX逻辑的类。我们来看看它们的一些。
1.4.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,可以为truefalse来决定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。
更完全的解释,请参照 Ajax.Request 参考Ajax选项参考
1.4.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属性。
更完全的解释,请参照 Ajax.Updater 参考Ajax选项参考
Chapter 2. prototype.js参考
2.1. JavaScript 类的扩展
prototype.js 包中加入功能的一种途径就是扩展已有的JavaScript 类。
2.2. Object类的扩展
Table 2.1. Object类的扩展
方法
类别
参数
描述
extend(destination, source)
static
destination: 任何对象, source: 任何对象
用从 sourcedestination复制所有属性和方法的方式 来提供一种继承机制。
extend(object)
instance
任何对象
用从传入的 object中复制所有属性和方法的方式 来提供一种继承机制。
2.3. Number类的扩展
Table 2.2. Number类的扩展
方法
类别
参数
描述
toColorPart()
instance
(none)
返回数字的十六进制描述, 当在HTML中转换为RGB颜色组件到HTML中使用的颜色。
2.4. Function类的扩展
Table 2.3. Function类的扩展
方法
类别
参数
描述
bind(object)
instance
object: 拥有这个方法的对象
返回预先绑定在拥有该函数(=方法)的对象上的函数实例, 返回的方法将和原来的方法具有相同的参数。
bindAsEventListener(object)
instance
object: 拥有这个方法的对象
返回预先绑定在拥有该函数(=方法)的对象上的函数实例, 返回的方法将把当前的事件对象作为它的参数。
让我们看看这些扩展的具体例子。
<input type=checkbox id=myChk value=1> Test?
<script>
    //declaring the class
    var CheckboxWatcher = Class.create();
 
    //defining the rest of the class implmentation
    CheckboxWatcher.prototype = {
 
       initialize: function(chkBox, message) {
            this.chkBox = $(chkBox);
            this.message = message;
            //assigning our method to the event
            this.chkBox.onclick = this.showMessage.bindAsEventListener(this);
       },
 
       showMessage: function(evt) {
          alert(this.message + ' (' + evt.type + ')');
       }
    };
 
 
    var watcher = new CheckboxWatcher('myChk', 'Changed');
</script>
2.5. String类的扩展
Table 2.4. String类的扩展
方法
类别
参数
描述
stripTags()
instance
(none)
返回一个把所有的HTML或XML标记都移除的字符串。
escapeHTML()
instance
(none)
返回一个把所有的HTML标记回避掉的字符串。
unescapeHTML()
instance
(none)
escapeHTML()相反。
2.6. document DOM 对象的扩展
Table 2.5. document DOM 对象的扩展