Posted on 2007-09-23 23:08
Sangplus 阅读(80)
评论(0) 编辑 收藏 网摘 所属分类:
javascript 、
asp.net
【Prototype 1.4.0】源码解读----全文注释版
http://www.cnblogs.com/me-sa/articles/605263.html
* Prototype JavaScript framework, version 1.4.0
* (c) 2005 Sam Stephenson <sam@conio.net>
*
* Prototype is freely distributable under the terms of an MIT-style license.
* For details, see the Prototype web site: http://prototype.conio.net/
* 这是一个JavaScript的框架,致力于简化动态的Web开发,完全按照面对对象的思想
* 进行Javascript开发,添加了迭代器的概念增强Javascript的设计能力。
* Prototype框架构思独特充满了技巧性的代码,方便易用的工具类!
*

/**//*--------------------------------------------------------------------------*/

/**//* 【Prototype】定义一个全局对象,提供一个全局的基本信息和工具 */

var Prototype =
{
Version: '1.4.0', //可以作为版本检测用
//用于脚本检测的正则表达式,经常使用所以放在这里起到全局常量的作用
ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',


emptyFunction: function()
{},//空函数

K: function(x)
{return x}//K方法返回参数本身,在后面经常用到
}


/**//*========================================================================================*/


/**//*
*【Class】对象的作用只有一个就是提供了一个定义类的模式
* 仅含有create 一个方法,返回一个构造函数。
* 一般使用如下
* var X = Class.create(); 返回一个类型
* 要使用 X 类型,需继续用 new X()来获取一个实例 这与C# JAVA类似
* 返回的构造函数会执行名为 initialize 的方法, initialize 是 Ruby 对象的构造器方法名字。
* 此时initialize方法还没有定义,其后的代码中创建新类型时会建立相应的同名方法,可以看作是一个抽象方法。
* 从C#角度讲可以理解为用Class.create()创建一个继承Object基类的类。
*
*/


var Class =
{

create: function()
{

return function()
{ //下面使用Apply方法传递参数是一个常用的技巧
this.initialize.apply(this, arguments);
}
}
}


/**//*========================================================================================*/


//Abstract是一个空对象,它的作用仅仅是作为一个抽象的命名空间,所有在该对象下定义的类都是抽象类
//从而从形式上与实体类分开
var Abstract = new Object();


/**//*
*Object是所有对象的基类,这个基类有两个静态方法
*/
//把Source的所有属性和方法传递给Destination,实现了继承的效果

Object.extend = function(destination, source)
{

for (property in source)
{
destination[property] = source[property];
}
return destination;
}
//观察Object的组成,需要参数中的object实现自己的inspect方法

Object.inspect = function(object)
{

try
{
if (object == undefined) return 'undefined';
if (object == null) return 'null';
return object.inspect ? object.inspect() : object.toString();

} catch (e)
{
if (e instanceof RangeError) return '';
throw e;
}
}


/**//*========================================================================================*/


//【Function】是所有函数对象的基类,可以通过对它的扩展实现对所有函数对象添加功能

/**//* 这里在绑定的时候旧可以传递参数而不是调用的时候才指定参数,bind方法接收多个参数
将函数绑定到第一个参数指定的对象上,并返回该方法的调用句柄
*/

Function.prototype.bind = function()
{
// $A()方法的作用是把参数专为数组
//数组的shift方法作用是删除数组的第一个元素
var __method = this, args = $A(arguments), object = args.shift();

return function()
{
return __method.apply(object, args.concat($A(arguments)));
//这里的$A(arguments)是条用返回函数句柄时传递的参数,不是bind方法的参数
}
}

/**//**
* 和bind一样,不过这个方法一般用做html控件对象的事件处理。所以要传递event对象
* 好像是重载了_method方法
*/


Function.prototype.bindAsEventListener = function(object)
{
var __method = this;

return function(event)
{
return __method.call(object, event || window.event);
}
}


/**//*========================================================================================*/

//【Function】是所有数值类型的基类


Object.extend(Number.prototype,
{

toColorPart: function()
{ //RGB-》16进制颜色
var digits = this.toString(16);
if (this < 16) return '0' + digits;
return digits;
},


succ: function()
{ //数值加一 var a=1; var b=a.succ; 那么b=2
return this + 1;
},


times: function(iterator)
{
//这里的参数iterator是一个迭代器作用就是循环调用指定次数的iterator函数
//$R(start,end,exclusive)是创建ObjectRnge对象的快捷方式
$R(0, this, true).each(iterator);
return this;
}
});


/**//*========================================================================================*/

//提供了一个方法these,要求参数是函数的句柄,可以有多个。作用就是返回第一个成功执行的函数的返回值

var Try =
{

these: function()
{
var returnValue;


for (var i = 0; i < arguments.length; i++)
{
var lambda = arguments[i];

try
{
returnValue = lambda();
break;

} catch (e)
{}
}

return returnValue;
}
}


/**//*========================================================================================*/

//定时器类用来实现Window.setInterval的效果,在给定时间间隔执行某一个函数,增加了对重复执行的控制S
var PeriodicalExecuter = Class.create();

PeriodicalExecuter.prototype =
{

initialize: function(callback, frequency)
{
//构造函数指定回调函数和执行频率,单位是秒
this.callback = callback;
this.frequency = frequency;
this.currentlyExecuting = false;

this.registerCallback();
},

/**//* 开始调用定时器,无需显示调用,在构造函数中就实现了自动调用,这一下面的
this.onTimerEvent.bind(this)如果写成this.onTimerEvent则this指针就会指向widows对象即setInterval的默认对象
从而不能正确的引用到下面两个函数上,也就失去了对正在执行函数的控制
*/


registerCallback: function()
{
setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
},
//下面的函数相当于是回调函数的一个代理, setInterval是到了指定的时间就会强制执行而这里
//加入了一个判断如果callback函数执行的时间超过了一个时间片,则阻止其被重复执行

onTimerEvent: function()
{

if (!this.currentlyExecuting)
{

try
{
this.currentlyExecuting = true;
this.callback();

} finally
{
this.currentlyExecuting = false;
}
}
}
}
/*使用举例:
function GetOnlineCount()
{//获得在线人数
}
new PeriodicalExecuter(GetOnlineCount,10)每10秒获取一次
*/


/**//*========================================================================================*/

/**//* 框架核心内容--------【基础工具类】
/*========================================================================================*/


/**//*document.getElementById(id)获取一个指定ID的结点,是这个方法的快捷方式和扩展
可以指定多个参数返回一个对象数组。参数也不一定是ID也可以是对象本身的引用,例如
$('id')等价于$($('id'))
*/

function $()
{
var elements = new Array();


for (var i = 0; i < arguments.length; i++)
{
var element = arguments[i];
if (typeof element == 'string')
element = document.getElementById(element);

if (arguments.length == 1)
return element;

elements.push(element);
}

return elements;
}


/**//*========================================================================================*/
//【String】类的扩展

//删除字符串中的HTML标记

Object.extend(String.prototype,
{

stripTags: function()
{
return this.replace(/<\/?[^>]+>/gi, '');
},
//删除字符串中的脚本块

stripScripts: function()
{
return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
},
//提取字符串中的所有脚本块,作为数组返回,每一个脚本作为一个数组元素

extractScripts: function()
{
var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
var matchOne = new RegExp(Prototype.ScriptFragment, 'im');

return (this.match(matchAll) || []).map(function(scriptTag)
{
return (scriptTag.match(matchOne) || ['', ''])[1];
});
},
//提取字符串中的脚本并执行

evalScripts: function()
{
return this.extractScripts().map(eval);
},
//将字符串进行html编码例如"<" --》"<"

escapeHTML: function()
{
var div = document.createElement('div');
var text = document.createTextNode(this);
div.appendChild(text);
return div.innerHTML;
},
//对字符串进行html解码例如"<"--》"<"

unescapeHTML: function()
{
var div = document.createElement('div');
div.innerHTML = this.stripTags();
return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
},
//将查询字符串格式的字符串转换为键值对数组
//例如var s="a=1&b=2&c=3"; var s2=s.toQueryParams(); s2为{a:1,b:2,c:3}

toQueryParams: function()
{
var pairs = this.match(/^\??(.*)$/)[1].split('&');

return