??xml version="1.0" encoding="utf-8" standalone="yes"?> Prototype?span class="object">Function对象的扩展比较简? 但却是非帔R要且非常有用的扩展。扩展主要包?个方? 他们被加CFunction.prototype? q样׃得Q意的函数对象都具备了q两个方法?q两个方法的主要用途在于将某个函数l定到特定的函数之上L行? Prototype?span class="object">Objectc进行的扩展主要通过一个静态函?span class="method">Object.extend(destination, source)实现了JavaScript中的l承?从语义的角度, Object.extend(destination, source)Ҏ有些不和逻辑, 因ؓ它事实上仅仅实现了从源对象到目标对象的全息拷贝。不q你也可以这栯为:׃目标对象拥有了所有源对象所拥有的特? 所以看上去像目标对象l承了源对象(q加以扩?一栗另? Prototype?span class="object">Object扩展了几个比较有用的静态方? 所有其他的cd以通过调用q些静态方法获取支持? Object.extend(destination, source)是Prototype实现的一个静态方? 在JavaScript中模拟了l承?事实? q个Ҏ的语义更加們于:动态地为某个对象添加属性或Ҏ。这个函数诏I了整个Prototype的框? 虽然核心思想是一致的, 但是在用中q是能够看到一些不同之? q些不同之处很微但是却值得一提? 1. 扩展现有对象的功?- Z们添加新的函? q是非常典型的对Numbercȝ扩展, ?span class="object">Number.prototype加入了一些额外的函数, 从而每个Number对象的实例都拥有q些Ҏ? 2. 定义q实现抽象类 q是Prototype中的代码D? 它向我们展示了定义ƈ实现抽象cȝ完整q程。这里首先定义了一?span class="object">Enumerablec? q是一个抽象类。这个抽象类的内? 有一?span class="method">_eachҎ被调用来完成一些逻辑。但是在整个Enumerable的范围内, 你无法找?span class="method">_eachҎ的具体实现。也是? Enumerable是一个抽象类, h一?span class="method">_each的抽象函数?所? 如果你还没有实现_eachq个抽象函数, 你是无法直接使用Enumerablecȝ。之后的代码比较明朗了, 使用Object.extendҎ, 所?span class="object">Enumerable的函数复制给Array.prototype, 然后?span class="object">Array.prototype中实?span class="method">_eachҎ, q样׃?span class="object">Array对象具备?span class="object">Enumerableq个抽象cȝ所有特性? ClasscdC在JavaScript中声明一个新的类, q过构造函数实例化q个cȝ机制。通过使用Class.create()Ҏ, 你实际上声明了一个新的类, q定义了一?span class="method">initialize()Ҏ作ؓ构造函? 一旦你在这个声明的cȝprototype中实C改该Ҏ, 你就可以使用new操作W来创徏q实例化一个类? 在JavaScript? 当你定义了一个新的函? 你实际上声明了一个新的类, 而这个函数本w就相当于类的构造函数?下面的代码向你展CZ两种不同的方式来创徏一个新?span class="object">Personc? ?span class="method">Person.prototype的定义也紧跟在函数定义之后? 当你通过函数的方式声明了一个类之后, 你就可以通过new操作W来实例化这个类。这? 你就可以调用cȝ成员函数来完成你的逻辑? 我们来ȝ一下创Z个新的类的实例的整个程和步骤: 1. 通过定义一个函数的方式(匿名或者实?来声明一个新的类. 在Prototype? 使用Class对象, 你可以以一个比较简单的方式来声明一个新的对象。通过使用Class.create(), prototypeZ创徏了一个默认的构造函数initialize(), 一旦你实现q一函数, 可以以一个类似Java中构造函数的方式来创Z个新的类的实例? 通过Classc? 你可以很ҎC用构造函数的方式创徏一个新的类, q对于JavaE序员来说或许更加容易被接受。下面我们列ZJava和JavaScript各自声明和创Z个新的类的代码对? 我们可以看到, 他们是如此相| 在开始所有的Prototype学习之旅之前Q我们首先对Prototype中最常用的一些公用函数做一些研IӞq些JavaScript函数诏I整?span class="Object">Prototype框架Q熟l用它们不仅有助于我们学习Prototype框架Q同时也为我们自q写JavaScript应用提供了独特的思\? $()为我们提供了一个快L方式Q通过id来读取一个对象,从而避免了我们在编写JavaScript代码时的重复而又冗长的代码段。然而,在某些情况下Q我们需要通过对象的name属性来d对象Qƈ对对象进行一定的操作Q此Ӟ$()Ҏ显得有些力不从心了。因而在q里Q我针对q种需求,q模?()ҎQ实C一个通过name来读取对象的函数? 事实上,getElementsByName()已经帮我们解决了大多数的问题。由于name在HTML的document中可以不唯一Q因而我们需要对此进行简单的处理Q当name唯一Ӟ直接q回单一对象Q当name不唯一Ӟq回一个数l?q已l与getElementsByName()本n的含义不同了Q当然这仅仅是ؓ了方便编E而已)?Function - 对Functioncȝ扩展
Knowledge Prepare - 知识准备
Source View - 源码解析
Function.prototype.bind = function() {
var __method = this; // q里的this表示bindҎ的调用? 是一个函数对?/span>
var args = $A(arguments); // q里?A(arguments)表示传入?span class="method">bindҎ的参? 不要与下面的$A(arguments)h
var object = args.shift(); // 调用args.shift()Ҏq回W一个参? 即目标对? 此时args为除ȝ一个参数的一个参数数l?/span>
return function() { // 不带有Q何的参数的函? 注意函数内部?A(arguments)的含?/span>
// 调用函数的applyҎ执行函数, 其中的object为目标对? args?span class="method">bindҎ中的参数列表(除了W一个参C外的参数构成的数l?
return __method.apply(object, args.concat($A(arguments)));// 事实? q里?A(arguments)一定是一个空数组
}
}
Function.prototype.bindAsEventListener = function(object) {
var __method = this; // q里的this表示bindҎ的调用? 是一个函数对?/span>
return function(event) { // 带有一个全局event参数的函?/span>
// 调用函数的callҎ执行函数, 其中的object为目标对? 全局的event对象作ؓ参数
return __method.call(object, event || window.event);
}
}
Field & Function Reference - 属性方法一?/h4>
Function ( 实例 ) - 扩展
Method / Property
Kind
Arguments
Description
bind(object[, arg1, arg2...])
Ҏ
objectQ目标对? 函数绑定到该对象上L?br />
argument list: 以参数列表的方式传入, 函数执行时所带的参数
一个实例方? 其调用者是一个函数对? 表示某个对象绑定到该函CL? 其中的第一个参数表C目标对? 其他参数作为函数执行时的参C?/td>
bindAsEventListener(object)
Ҏ
objectQ目标对?/td>
一个实例方? 其调用者是一个函数对? 表示某个对象绑定到该函CL? 参数为目标对? 在函数执行时全局的Event对象作ؓ参数传入
Analysis & Usage - 分析与?/h4>
]]>Object - 对Objectcȝ扩展
Source View - 源码解析
Object.extend = function(destination, source) { // 一个静态方法表C? 目标对象拥有源对象的所有属性和Ҏ
for (var property in source) {
destination[property] = source[property]; // 利用动态语a的特? 通过赋值动态添加属性与Ҏ
}
return destination; // q回扩展后的对象
}
Object.extend(Object, {
inspect: function(object) { // 一个静态方? 传入一个对? q回对象的字W串表示
try {
if (object == undefined) return 'undefined'; // 处理undefined情况
if (object == null) return 'null'; // 处理null情况
// 如果对象定义了inspectҎ, 则调用该Ҏq回, 否则q回对象的toString()?/span>
return object.inspect ? object.inspect() : object.toString();
} catch (e) {
if (e instanceof RangeError) return '...'; // 处理异常情况
throw e;
}
},
keys: function(object) { // 一个静态方? 传入一个对? q回该对象中所有的属? 构成数组q回
var keys = [];
for (var property in object)
keys.push(property); // 每个属性压入到一个数l中
return keys;
},
values: function(object) { // 一个静态方? 传入一个对? q回该对象中所有属性所对应的? 构成数组q回
var values = [];
for (var property in object)
values.push(object[property]); // 每个属性的值压入到一个数l中
return values;
},
clone: function(object) { // 一个静态方? 传入一个对? 克隆一个新对象q返?/span>
return Object.extend({}, object);
}
});
Field & Function Reference - 属性方法一?/h4>
Object ( 静?) - 扩展
Method / Property
Kind
Arguments
Description
extend(destination, source)
静态方?/td>
L对象
inspect(object)
静态方?/td>
L对象
keys(object)
静态方?/td>
L对象
values(object)
静态方?/td>
L对象
clone(object)
静态方?/td>
L对象
Analysis & Usage - 分析与?/h4>
Object.extend(Number.prototype, {
toColorPart: function() {
var digits = this.toString(16);
if (this < 16) return '0' + digits;
return digits;
},
......
});
var Enumerable = {
each: function(iterator) {
var index = 0;
try {
this._each(function(value) {
try {
iterator(value, index++);
} catch (e) {
if (e != $continue) throw e;
}
});
} catch (e) {
if (e != $break) throw e;
}
},
......
}
Object.extend(Array.prototype, Enumerable);
Object.extend(Array.prototype, {
_each: function(iterator) {
for (var i = 0; i < this.length; i++)
iterator(this[i]);
},
......
}
]]>Class - cd?/h3>
Knowledge Prepare - 知识准备
var Person = function(name) { // 一个匿名函? q将q个函数赋值给一?span class="object">Person变量, 此时Person成ؓ一个类
this.name = name;
}
function Person(name) { // 直接定义一个叫?span class="object">Person的函数表C?span class="object">Personc?/span>
this.name = name;
}
Person.prototype = { // 定义Person的prototype?/span>
printName: function() { // 定义一个print函数
alert(this.name);
}
}
var person = new Person("Joe Smith"); // 使用new操作W来新徏一?span class="Object">Person的实? q赋l变?span class="method">person
person.printName(); // person可以看作是一个实例的引用(reference), 所以可以通过q个引用来调?span class="Object">PersoncM的成员函?/span>
2. 如果有必? 定义q个新的cȝprototype?
3. 使用new操作W紧跟你所定义的函数来创徏一个新的类的实? 一旦JavaScript~译器碰Cnew操作W? 它实际上创徏了一个空的类实例变量.
4. 所有这个类的prototype域中的属性与Ҏ复制到这个新的实例中, q将其成员函C所有的this指针指向q个新创建的实例.
5. 接下? 执行紧跟?span class="method">new操作W后面的那个函数.
6. 当你执行q个函数? 如果你试囑֯一个不存在的属性进行赋? JavaScript~译器将自动Z在这个实例范围内新创个属?
7. 函数执行完毕? 这个初始化完成的实例返? Source View - 源码解析
var Class = { // 全局静态类, 用于声明一个新的类q提供构造函数支?/span>
create: function() {
return function() { // q回一个函? 代表着q个新声明的cȝ构造函?/span>
// 一个命名ؓinitialize的函数将被这个类实现作ؓcȝ构造函?/span>
this.initialize.apply(this, arguments);// initialize函数在你实例化一个变量的时候被调用执行(即上?个步骤中的第5?
}
}
}
Field & Function Reference - 属性方法一?/h4>
Class ( 静?)
Method / Property
Kind
Arguments
Description
create()
静态方?/td>
/
用于声明一个新的类q提供了一个名为initialize构造函数支?/td>
Analysis & Usage - 分析与?/h4>
var Person = Class.create(); // cȝ声明 |public class Person { // cȝ声明
Person.prototype = { | private String name;
initialize: function(name) { // 构造函?/span> | public Person(String name){ // 构造函?/span>
this.name = name; | this.name = name;
} | }
printName: function() { // 成员函数 | public void printName(){ // 成员函数
alert(this.name); | System.out.println(name);
} | }
} |}
var person = new Person("Joe Smith");// 创徏实例 |Person person = new Person("Joe Smith");// 创徏实例
person.printName(); // 函数调用 |person.printName(); // 函数调用
]]>Basic - 基础代码
Source View - 源码解析
var Prototype = { // 定义一?span class="Object">Prototype对象Q封装了一些简单的静态函数和变量
Version: '1.5.0_rc1', // 定义当前Prototype框架的版本号
ScriptFragment: '(?:
Field & Function Reference - 属性方法一?/h4>
Prototype ( 静?)
Method / Property
Kind
Arguments
Description
Version
静态属?/td>
/
表示Prototype框架的版本号
ScriptFragment
静态属?/td>
/
表示script代码D늚正则表达?/td>
emptyFunction
静态方?/td>
/
q回一个什么都不做的空函数
K
静态方?/td>
L对象
q回传入的参?/td>
$() ( 静?)
Method / Property
Kind
Arguments
Description
$()
静态方?/td>
string或者Q意对? 参数数量不限
Ҏ参数的类型和数量q回DOM操作的结? 传入的参CؓstringӞq回document.getElementById所d的对? 传入的参Cؓ非stringcd的对象时, 直接q回参数本n; 当参C数是1个时, 直接q回上述操作所得的l果; 当参C数大?个时, 每个参数操作的l果l成一个对象数l返?/td>
Abstract ( 静?)
Method / Property
Kind
Arguments
Description
Abstract
c?/td>
/
一个全局的对? 可以理解Z个命名空? 成ؓ一个抽象基c?/td>
Try ( 静?)
Method / Property
Kind
Arguments
Description
these
静态方?/td>
多个有待依次执行的函?/td>
q回W一个成功执行的函数的执行结?/td>
PeriodicalExecuter ( 实例 )
Method / Property
Kind
Arguments
Description
callback
属?/td>
/
构造函数实例化时初始化的属? 定义定时器重复执行时真正需要调用的函数
frequency
属?Number)
/
构造函数实例化时初始化的属? 定义定时器重复执行的旉间隔
currentlyExecuting
属?Boolean)
/
在整个定时器执行q程中表C是否当前执行的标志, 可以作ؓ执行q程中的同步信号?/td>
timer
属?/td>
/
一个内部变? 在registerCallbackҎ调用window.setInterval时记录该函数的返回? 用以lstopҎ使用
registerCallback
Ҏ
/
在构造函数初始化完成时调用执? 也可以直接调用该函数启动定时? 在函数内部通过调用window.setIntervalҎ完成定时器功?/td>
stop
Ҏ
this.timer, 即重复执行时调用setInterval的返回?/td>
用于暂停定时? 通过实例变量调用完成
onTimerEvent
Ҏ
/
一个内部方? 真正调用callback完成函数执行
Analysis & Usage - 分析与?/h4>
Extension - 扩展
]]>
http://p-x1984.javaeye.com/blog/196906
]]>
]]>
2.prototype.js 官方api文档
http://prototypejs.org/api/
3.开始学习prototype.js
http://www.prototypejs.org/learn
4.prototype.js sample
http://prototype-window.xilinus.com/samples.html
5.prototype.js讨论?br /> http://groups.google.com/group/Prototypejs/topics
6.precipitant的学习笔讎ͼ貌似看到一Qƈ没有扑ֈ二?^_^
http://blog.csdn.net/precipitant/archive/2007/10/13/1823220.aspx
7.phphot写的prototype.js教程
http://blog.csdn.net/phphot/archive/2007/10/10/1818938.aspx
8.一个ajax的讨?br /> http://bbs.okajax.com/forum-13-1.html
9.prototype.js开发应用手?br /> http://bbs.blueidea.com/thread-2812502-1-1.html
10.一个ajax框架介绍的网?br /> http://ajaxian.com/resources/
11.以下几个|站也是学习prototype.js的不错的|站,含有prototype.js中文教程
https://compdoc2cn.dev.java.net/prototype/html/prototype.js.cn.html
http://www.lvjiyong.com/item/jquery-with-prototype-using-ajax
http://591wap.cn/works/prototype/using_ajax_request.html
12.JAVA.NET上的prototype.js学习W记
https://compdoc2cn.dev.java.net/prototype/html/prototype.js.cn.html
13.prototype.js源文件以及中英文手册下蝲,L步这?br /> prototype.js教程及prototype中文手册
Position?/span>prototype中定义的一个对象,提供了操?/span>DOM中与位置相关的方法,要很好的理解元素在页面中的位|,可以参考这文章:Relatively Absolute
具体代码如下Q按照代码说_其中英文是作者的注释Q中文红色的才是偶的说明或翻译英文的注释Q采用顶式注释法(注释在要说明的代码的上面)说明
// set to true if needed, warning: firefox performance problems
// NOT neeeded for page scrolling, only if draggable contained in
// scrollable elements
//只有在用拖动的时候元素包含在有滚动条的元素中才需要设|ؓtrue
includeScrollOffsets: false,
// must be called before calling withinIncludingScrolloffset, every time the
// page is scrolled
//当页面被scrolled后,使用withinIncludingScrolloffset的时候需要先调用q个Ҏ
prepare: function() {
//横向滚动条滚动的距离
this.deltaX = window.pageXOffset
|| document.documentElement.scrollLeft
|| document.body.scrollLeft
|| 0;
//U向滚动条滚动的距离
this.deltaY = window.pageYOffset
|| document.documentElement.scrollTop
|| document.body.scrollTop
|| 0;
},
//元素׃滚动条偏Uȝ总距?/span>
realOffset: function(element) {
var valueT = 0, valueL = 0;
do {
valueT += element.scrollTop || 0;
valueL += element.scrollLeft || 0;
element = element.parentNode;
} while (element);
return [valueL, valueT];
},
//元素在页面中?/span>offsetParent累积?/span>offsetQ当offsetParent都没有滚动条Ӟ是元素在页面中的位|?/span>
cumulativeOffset: function(element) {
var valueT = 0, valueL = 0;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
} while (element);
return [valueL, valueT];
},
//元素相对?/span>containing block("nearest positioned ancestor")的位|,也就是相对于最q的一?/span>position讄?/span>relative或?/span>absolute的祖先节点的位置Q如果没有就是相对于 body的位|,?/span>style.topQ?/span>style.left一P
positionedOffset: function(element) {
var valueT = 0, valueL = 0;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
if (element) {
if(element.tagName==’BODY’) break;
var p = Element.getStyle(element, 'position’);
if (p == 'relative’ || p == 'absolute’) break;
}
} while (element);
return [valueL, valueT];
},
//offsetParent
offsetParent: function(element) {
if (element.offsetParent) return element.offsetParent;
if (element == document.body) return element;
while ((element = element.parentNode) && element != document.body)
if (Element.getStyle(element, 'position’) != ’static’)
return element;
return document.body;
},
// caches x/y coordinate pair to use with overlap
//判断指定的位|是否在元素?/span>
within: function(element, x, y) {
if (this.includeScrollOffsets)
return this.withinIncludingScrolloffsets(element, x, y);
this.xcomp = x;
this.ycomp = y;
this.offset = this.cumulativeOffset(element);
return (y >= this.offset[1] &&
y < this.offset[1] + element.offsetHeight &&
x >= this.offset[0] &&
x < this.offset[0] + element.offsetWidth);
},
//?/span>within差不多,不过考虑到滚动条Q也许是在元素上面,但不是直接在上面Q因为滚动条也许已经使元素不可见?/span>
withinIncludingScrolloffsets: function(element, x, y) {
var offsetcache = this.realOffset(element);
this.xcomp = x + offsetcache[0] - this.deltaX;
this.ycomp = y + offsetcache[1] - this.deltaY;
this.offset = this.cumulativeOffset(element);
return (this.ycomp >= this.offset[1] &&
this.ycomp < this.offset[1] + element.offsetHeight &&
this.xcomp >= this.offset[0] &&
this.xcomp < this.offset[0] + element.offsetWidth);
},
// within must be called directly before
//在调用这个方法前Q必d调用withinQ返回在with指定的位|在水^或者垂直方向上占用的百分比
overlap: function(mode, element) {
if (!mode) return 0;
if (mode == 'vertical’)
return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
element.offsetHeight;
if (mode == 'horizontal’)
return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
element.offsetWidth;
},
//q回元素相对面的真实位|?/span>
page: function(forElement) {
var valueT = 0, valueL = 0;
var element = forElement;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
// Safari fix
if (element.offsetParent==document.body)
if (Element.getStyle(element,’position’)==’absolute’) break;
} while (element = element.offsetParent);
element = forElement;
do {
if (!window.opera || element.tagName==’BODY’) {
valueT -= element.scrollTop || 0;
valueL -= element.scrollLeft || 0;
}
} while (element = element.parentNode);
return [valueL, valueT];
},
//讄target?/span>source的位|,大小
clone: function(source, target) {
var options = Object.extend({
setLeft: true,
setTop: true,
setWidth: true,
setHeight: true,
offsetTop: 0,
offsetLeft: 0
}, arguments[2] || {})
// find page position of source
source = $(source);
var p = Position.page(source);
// find coordinate system to use
target = $(target);
var delta = [0, 0];
var parent = null;
// delta [0,0] will do fine with position: fixed elements,
// position:absolute needs offsetParent deltas
if (Element.getStyle(target,’position’) == 'absolute’) {
parent = Position.offsetParent(target);
delta = Position.page(parent);
}
// correct by body offsets (fixes Safari)
if (parent == document.body) {
delta[0] -= document.body.offsetLeft;
delta[1] -= document.body.offsetTop;
}
// set position
if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px’;
if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px’;
if(options.setWidth) target.style.width = source.offsetWidth + 'px’;
if(options.setHeight) target.style.height = source.offsetHeight + 'px’;
},
//?/span>element?/span>position讄?/span>absolute的模?/span>
absolutize: function(element) {
element = $(element);
if (element.style.position == 'absolute’) return;
Position.prepare();
var offsets = Position.positionedOffset(element);
var top = offsets[1];
var left = offsets[0];
var width = element.clientWidth;
var height = element.clientHeight;
element._originalLeft = left - parseFloat(element.style.left || 0);
element._originalTop = top - parseFloat(element.style.top || 0);
element._originalWidth = element.style.width;
element._originalHeight = element.style.height;
element.style.position = 'absolute’;
element.style.top = top + 'px’;;
element.style.left = left + 'px’;;
element.style.width = width + 'px’;;
element.style.height = height + 'px’;;
},
//?/span>element?/span>position讄?/span>absolute的模?/span>
relativize: function(element) {
element = $(element);
if (element.style.position == 'relative’) return;
Position.prepare();
element.style.position = 'relative’;
var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
element.style.top = top + 'px’;
element.style.left = left + 'px’;
element.style.height = element._originalHeight;
element.style.width = element._originalWidth;
}
}
// Safari returns margins on body which is incorrect if the child is absolutely
// positioned. For performance reasons, redefine Position.cumulativeOffset for
// KHTML/WebKit only.
if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
Position.cumulativeOffset = function(element) {
var valueT = 0, valueL = 0;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
if (element.offsetParent == document.body)
if (Element.getStyle(element, 'position’) == 'absolute’) break;
element = element.offsetParent;
} while (element);
return [valueL, valueT];
}
}
l于?/span>Prototype的所有部分都写完了,哈哈Q越来越佩服自己的耐力?/span>
下一步决定写?/span>Scriptaculousq个行的效果库
q几天在论坛和博客上看到很多人问Prototype1.5怎么下蝲Qؓ什么下载这么困隑֑Q?/span>
Prototype的官方网站是Q?/span>http://prototype.conio.net/Q如果你一下子找不刎ͼ?/span>google上搜?/span>Prototype找C
下蝲当然要到官方|站下蝲了,但是问题?/span>Prototype官方|站更新太慢Q首上的下载连接还?/span>prototype1.4的,而且只是一个单独的js文g
那么怎么下蝲最新版本的呢?
1Q如果你只想得到一个单独的js文g使用的话Q其实官方网站提供了最新版1.5的下?/span>, 下面q接是下蝲地址?/span>http://dev.rubyonrails.org/browser/trunk/railties/html/javascripts/prototype.js?format=raw
2Q如果你惛_到详l的源文件以及测试代码,需要通过svn下蝲Q用下面的命o可以了Q?/span>svn co http://dev.rubyonrails.org/svn/rails/spinoffs/prototype
如果你没?/span>svn的话Q我已经下蝲打包了传?/span>51js论坛中,查看下面q接的帖子中有下载的Q?/span>http://bbs.51js.com/viewthread.php?tid=65070&highlight=prototype
惛_很多prototype爱好者都一直在{待着prototype1.5的发布,虽然{待的时间很长,但是q一令hȀ动的一天终于到来了
因ؓ|友提醒Q今天访?/span>prototype|站Q发现原来的|址已经自动跌{到新的网站去了,作者用了一个独立的域名http://www.prototypejs.org/
刚才?/span>google里搜?/span>prototypeQ发现搜索结果中出现的已l是新网站了Q?/span>google爬虫也蛮勤快的嘛
更让人高兴的是,一向被病的文档问题q一版有了非常大的提高,可以说是有了质的飞跃Q以前的版本基本上没有文档,要用只有自q解了Q?/font>
现在在它的官方网站上有专门的API参考以及一些用的例子Q看来作者真正的关于q个问题来了Q?/span>prototype爱好者应该高兴一把了哈哈Q赶快到prototype官方|站下蝲?/span>Engoy?/span>如果感觉阅读英文是一U折的话,可以参考我以前写的prototype 1.5使用指南pd文章.
Q-声明Q该使用指南文章{载,׃是来源于多次转蝲Q未扑ֈ原出处。再ơ感谢作者与译人员?/font>
q一部分提供了很多与表单操作有关的功能,包括以下部分Q当通过$Ҏq回元素Ӟ可以直接通过$(element).method()调用Q?/span>
Form对象Q提供了操作整个表单的一些方?/span>
Form.Element对象Q提供了操作某个表单元素的方?/font>
TimedObserverc:周期性表单监视器Q当表单元素值改变的时候执行一个回调函敎ͼ?/span>Form?/span>Element两种cd
EventObserverc:利用事g来监视表单元素,当表单元素值改变的时候执行一个回调函敎ͼ?/span>Form?/span>Element两种cd
Form对象Q?/span>
reset(form)Q?/span>form.reset()
serializeElements(elements)Q将elements中的元素序列化,是q回指定的所有元素的queryString的Ş式,便于?/span>xmlhttp或其他地方?/span>
serialize(form)Q序列化整个表单
getElements(form)Q返回表单的所有可序列化元?/font>
getInputs(form, typeName, name)Q返回所有符?/span>typeName?/span>name?/span>input元素
disable(form)Q整个表单处于不可用状?/font>
enable(form) Q是整个表单可用
findFirstElement(form)Q返回类型ؓ'input’, ’select’, 'textarea’的第一个可用的非隐藏元?/span>
focusFirstElement(form)QfindFirstElement(form)q回的元素得到焦?/span>
Form.Element对象Q?/span>
focus(element) select(element)Q?/span>html元素内置Ҏ的封装,除了q回元素本n
serialize(element)Q序列化指定的表单元素,q回key=value的Ş式,q回?/span>string已经encodeURIComponent?/span>
getValue(element)Q返回元素的?/font>
clear(element)Q清除元素的?/font>
present(element)Q判断元素的值是否非I?/font>
activate(element)Q元素获得焦点
disable(element)Q元素不可?/font>
enable(element)Q是元素可用
$F = Form.Element.getValue 方便使用
Form.Element.Observer以及Form.Observerc:
周期性监视表单元素,如果表单或表单元素的值有改变Ӟ执行执行一个回调函敎ͼ使用方式如下Q?/font>
var oser=new Form.Element.Observer(element, frequency, callback)
or oser=new Form.Observer(form, frequency, callback)
callback可以定义两个参数 form/element?/span>Form.serialize()/value
Form.Element.EventObserver?/span>Form.EventObserverc:
q两个类跟上面的差不多,只是不是周期性的监视Q而是利用元素?/span>change?/span>click事g来监视表单元素的变化Q当发生变化时执?/span>callbackQ参数跟上面一?/span>
在介l?/span>Prototype?/span>Event对象前先介绍一下浏览器中的事g模型Q浏览器中的事g主要?/span>HTML事g、鼠标事件和键盘事gQ前两种事g比较好理解,q里主要解释一下键盘事件以及它?/span>IE?/span>firefox中的区别
键盘事g包括keydown?/span>kepress?/span>keyup三种Q每ơ敲击键盘都?/span>(依次Q?/span>)触发q三U事Ӟ其中keydown?/span>keyup是比较低U的接近于硬件的事gQ通俗的理解是q两个事件可以捕获到你敲M键盘中某个键Q?/span>keypress是相对于字符层面的较为高U点的事Ӟq个事g能够捕捉C键入了哪个字W。可以这L解,如果你敲MA键,keydown?/span>keyup事g只是知道你敲MA键,它ƈ不知道你敲的是大写的A(你同时按下了Shift?/span>)q是敲的是小?/span>aQ它是以"?/span>"为单位,你敲入了大写?/span>AQ它只是当成你敲下了shift?/span>A两个键而已Q但?/span>keypress可以捕捉C是敲入的大写?/span>Aq是写?/span>a
q要理解一个概忉|键盘中的键分为字W?/span>(可打?/span>)键和功能?/span>(不可打印)Q功能键包括Backspace, Enter, Escape, the arrow keys, Page Up, Page Down, and F1 through F12 {?/span>
下面说一下键盘事件的具体使用ҎQ?/font>
键盘事g?/span>event对象中包含一?/span>keyCode属性,IE中只有这一个属性,当ؓkeydown?/span>keyup 事g是,keycode属性表CZ具体按下的键(也称?/span>virtual keycode)Q当捕捉的是keypress事g?/span>keyCode属性指的是你键入的字符(character code)
?/span>firefox中情冉|些不同,event对象包含一?/span>keyCode属性和一?/span>charCode属性,keydown?/span>keyup事g的时候,keyCode表示的就是你具体按的键,charCode?/span>0Q当捕捉的是keypress事gӞkeyCode?/span>0Q?/span>charCode指的是你按下的字W?/span>
当捕捉的?/span>keypress事gӞ当你按的是可打印字符ӞkeyCode?/span>0Q?/span>charCode指的是你按下的字W的键|当你按的是不可打印字W时Q?/span>keyCode为按下的键的键|charCode?/span>0
注意Q功能键不会触发keypress事gQ因?/span>keypress对应的就是可打印的字W,但是有一?/span>IE?/span>FF 中的区别Q你按下一个字W键的同时按?/span>alt键,?/span>IE中不触发keypress事gQ但是在ff中可触发Q我发现?/span>IE中按?/span>ctrl键的时候只有按?/span> q键会触发事g其他的要么不会触发事Ӟ要么被浏览器IE自n捕获了,例如你按?/span>ctrl_AQ全选某个东西,你按ctrl_S保存文gQ但是在FF中就好多了,事g都是先传递到|页Q再向外传?/span>
鉴于IE?/span>FF中的区别Q如果你比较懒的话,只?/span>keydow?/span>keyup事gQ这两种事g的用在IE?/span>FF中基本上没有区别Q也不要捕获ctrl_A{被览器定义ؓ快捷键的事g
键盘事gevent对象q有三个其他的属?/span>altKey, ctrlKey, and shiftKey 来判断你按下一个键的时候是否按下了alt{键Q这三个属性用比较简单,三种事g都可以用,也不存在ie?/span>ff的兼Ҏ问?/span>
?/span>Prototype中的Event中又如下属性:
KEY_BACKSPACE: 8,
KEY_TAB: 9,
KEY_RETURN: 13,
KEY_ESC: 27,
KEY_LEFT: 37,
KEY_UP: 38,
KEY_RIGHT: 39,
KEY_DOWN: 40,
KEY_DELETE: 46,
KEY_HOME: 36,
KEY_END: 35,
KEY_PAGEUP: 33,
KEY_PAGEDOWN: 34,
以及下面的方法:
element(event) Q返回触发事件的元素
isLeftClick(event) Q判断是否按下的左键
pointerX(event) Q事件触发时鼠标的横坐标Q对于非鼠标事gQ在ff中没有此信息Q但?/span>ie中有Q?/span>
pointerY(event)Q事件触发时鼠标所在位|的U坐?/font>
stop(event)Q阻止事件向上传播和览器的默认处理Ҏ
findElement(event, tagName) Q找到触发事件的元素的所有祖先元素中?/span>tagName?/span>tagName的一个元?/span>
observe(element, name, observer, useCapture)Q注册事件处理函?/font>
stopObserving(element, name, observer, useCapture)Q撤销注册的事?/font>
q部分提供了很多(写的都有点烦?/span>)方便的操?/span>dom的方法:包含有名?/span>$Ҏ?/span>document.getElementsByClassNameҎQ以?/span>Element对象?/span>Insertion对象
以下部分一个一个的详细介绍Q?/font>
$(element)Q?/span>getElementById的封装,element可以是一个元素的id或元素本w,也可以是一个数l,q时q回一个数l,使用$ҎQ会自动调用Element.extend(element)ҎQ这L话元素可以直接调用 Element中的Ҏ, 例如Element.hide(element)可以写成q样$(element).hide()
document.getElementsByClassName(className, parentElement): Ҏclass选择元素
Element.extend(element): 扩展elementQelement可以直接调用Element?/span>Form.Element?/span>Form中定义的Ҏ
Element对象的方法:
visible: function(element)Q判?/span>element是否可见, 参数element可以是元素本w或元素id(下面的方面的参数基本上都是这L)
toggle: function(element)Q反?/span>element的可见?/span>
hide: function(element)Q隐藏元?/span>
show: function(element)Q显C元?/span>
remove: function(element)Q移除元?/span>
update: function(element, html) Q?/span>html更新element的内容,html中的script会执?/span>(下同)
replace: function(element, html)Q将element替换?/span>html
inspect: function(element)Q?/span>element的字W串表示
recursivelyCollect: function(element, property): 递归攉, 例如Element.recursivelyCollect(element, "parentNode")q回element所有的先节点, 注意只返?/span>nodeType == 1的元素,也就是不q回文本元素
ancestors: function(element): {同于上面的例子Q返回元素的所有祖先节?/span>
descendants: function(element): q回所有子孙节?/span>
immediateDescendants: function(element)Q返回元素的直接的子孙节?/span>(子节?/span>)的数l?/span>
previousSiblings: function(element)Q返回元素前面的兄弟节点
nextSiblings: function(element)Q返回位于元素后面的兄弟节点
siblings: function(element)Q返回元素所有的兄弟节点
match: function(element, selector)Q?/span>Selector?/span>matchҎ匚w元素(Selector在后面介绍), selector参数是一?/span>css selector表达式或?/span>Prototype中的一?/span>Selector实例Q如?/span>element匚wselector则返?/span>trueQ否则返?/span> falseQ例如对于一?/span>className?/span>logcss?/span>div来说Q下面的表达式返?/span>true, $(element).match("div.logcss") 待箋。?/span>
up(element, expression, index)Q利?/span>Selector.findElementҎ扑ֈelement元素的祖先节点中W合表达?/span>expression的所有元素组成的数组索引?/span>index的元素,也可以忽?/span>expression(默认?/span>*Q表C匹配所有元?/span>)?/span>index(默认?/span>0)Q直接这栯?/span>up(element, index)?/span>up(element)
down(element, expression, index)Q跟up一P只是q回的是子孙节点
previous(element, expression, index)Q返回前面的兄弟节点
next(element, expression, index)Q返回后面的兄弟节点
getElementsBySelector(element,args)Q?/span>Selector.findChildElements(element, args)的封装,args表示可以传递多个参敎ͼ每个参数是一?/span>css selector表达式,q回element的子孙节点中W合M一?/span>css selector表达式的元素l成的数l?/span>
getElementsByClassName(element, className)Q返?/span>element中的子孙节点中符?/span>clsssName的元?/span>
readAttribute(element, name)Q?/span>return $(element).getAttribute(name)Q之所以添加这个方法是因ؓ?/span>IE?/span>Safari(Mac)?/span>getAttribute不是一个真正的函数Q它没有call?/span>apply{方法,所以在很多时候调用会出现错误(Prototype中很多地方用了函数的这两个Ҏ)Q例如下面的例子(官方文档中的一个例?/span>)Q就只能使用readAttributeQ?/span>
<div id="widgets">
<div class="widget" widget_id="7">…</div>
<div class="widget" widget_id="8">…</div>
<div class="widget" widget_id="9">…</div>
</div>
$$(’div.widget’).invoke(’readAttribute’, 'widget_id’)
// ["7", "8", "9"]
getHeight: function(element)Q返回元素高度,return element.offsetHeight
classNames: function(element)Q返回一?/span>Element.ClassNames对象Q改对象提供对元?/span>class的操作,包括add?/span>remove?/span>set{,一般很用,使用Element.addClassName{方法就可以?/span>(在下面)
hasClassName: function(element, className) Q判?/span>element是否含有className
addClassName: function(element, className) Q给elementd一?/span>class
removeClassName: function(element, className) Q移除元素中的一?/span>class
observe()Q调?/span>Event对象(Prototype中的Q将在后面介l?/span>)?/span>observeҎ为元素注册事?/span>handle
stopObserving() Q移除注册的事ghandle
cleanWhitespace: function(element)Q移除元素中I白的文本子节点
empty: function(element)Q判断元素是否ؓI?/span>
childOf: function(element, ancestor) Q判?/span>element是否?/span>ancestor的子孙节?/span>
scrollTo: function(element) Q滚动条Ud到元素所在的地方
getStyle: function(element, style) Q得到元素某?/span>css样式的|例如$(element).getStyle("float")
setStyle: function(element, style) Q设|元素的css样式Q?/span>style十一个对象,例如element.setStyle({left: "40px", "background-color":"#666"})
getDimensions: function(element) Q得到元素的寸Q即使元素是隐藏的也可以正确的返回,q回 return {width: originalWidth, height: originalHeight}q样的关联数l?/span>
makePositioned: function(element) Q当元素?/span>position css属性ؓstatic或不存在使,次属性更改ؓrelative
undoPositioned: function(element) Q跟makePositioned相反的操?/span>
makeClipping: function(element) Q把元素变成clipping(切片)Q也是讄元素?/span>overflow属性ؓhidden
undoClipping: function(element)Q反转上面的Ҏ对元素所做的修改
hasAttribute(element)Q判断元素是否有某个属?/span>
Element对象的方法是不是不少啊,哈哈Q下面介l有?/span>Insertion的四个类
Insertion.BeforeQ将内容插入到元素的前面Q内容在元素外面
Insertion.TopQ将内容插入到元素的剙Q内容在元素里面
Insertion.BottomQ将内容插入到元素的底部Q内容在元素里面
Insertion.AfterQ将内容插入到元素后面,内容在元素外?/span>
使用它们的方法比较简单:new Insertion.where(element, content)Q其?/span>where表示上面?/span>Before?/span>Top{,content?/span>html字符Ԍ注意其中javascript片断会执?/span>
l于写完了,Prototype?/span>ElementҎq真不少
虽然以前觉得自己?/span>Prototypeq比较熟悉,写的也有点篏Q但是发现自己收获仍然挺大的Qؓ了写些方法的具体作用和用法,必须自己一行行的把Prototype的代码弄清楚Q自己?/span>Prototype中很多精巧的写法有了更深ȝ认识和理?/span>
写这个教E的主要目的是ؓ了给大家一个快速的参考,大家q是对照着源代码看才会真正有所提高
q时我第一ơ写比较完整的一个教E,错误q稚的地方在所隑օQ希望大家批评指正,互相学习提高Q?/font>
Selector是利?/span>css selector来匹配选择面元素的,所以要理解Selector首先应该?/span>css selector有所理解Q下面是css2 selector的语法,当然很多览器只是支持其中的一部分Q?/span>Prototype 中的Selector主要支持tag选择器?/span>class选择器和id选择器,q有属?/span>(attribute)选择器,基本上包含我们^时所用的所有类?/span>
The following table summarizes CSS2 selector syntax, 详细的可以看http://www.w3.org/TR/REC-CSS2/selector.html:
Pattern |
Meaning |
Described in section |
* |
Matches any element. |
|
E |
Matches any E element (i.e., an element of type E). |
|
E F |
Matches any F element that is a descendant of an E element. |
|
E > F |
Matches any F element that is a child of an element E. |
|
E:first-child |
Matches element E when E is the first child of its parent. |
|
E:link E:visited |
Matches element E if E is the source anchor of a hyperlink of which the target is not yet visited (:link) or already visited (:visited). |
|
E:active E:hover E:focus |
Matches E during certain user actions. |
|
E:lang(c) |
Matches element of type E if it is in (human) language c (the document language specifies how language is determined). |
|
E + F |
Matches any F element immediately preceded by an element E. |
|
E[foo] |
Matches any E element with the “foo” attribute set (whatever the value). |
|
E[foo=”warning”] |
Matches any E element whose “foo” attribute value is exactly equal to “warning”. |
|
E[foo~=”warning”] |
Matches any E element whose “foo” attribute value is a list of space-separated values, one of which is exactly equal to “warning”. |
|
E[lang|=”en”] |
Matches any E element whose “lang” attribute has a hyphen-separated list of values beginning (from the left) with “en”. |
|
DIV.warning |
HTML only. The same as DIV[class~=”warning”]. |
|
E#myid |
Matches any E element ID equal to “myid”. |
Selector中包?/span>Selector对象和类Q?/span>
Selector对象h下面两个ҎQ?/span>
match(element)Q元素是否与?/span>selector匚wQ在Element中已l介l了
findElements(parentNode)Q?/span>parentNode中所有匹配本selector的子孙元素列?/span>
使用Ҏ也很?/span> var s=new Selector(expression); s.match(element); s.findElements($(element))Q其?/span>expression可以是如下方?/span> "div"?/span>"#id"?/span>".class"?/span>"div#id"?/span>"div[attribute]"?/span>"div[attribute=fff]"?/span>"div[attribute!=sdf]"
其中Selector也有几个静态方法,它们分别是:
matchElements(elements, expression)Q返?/span>elements中符?/span>expression的元素列?/span>
findElement(elements, expression, index)Q返?/span>elements中符?/span>expression的元素列表中索引?/span>index的元?/span>
findChildElements(element, expressions)Q找?/span>element的子孙元素中W合expressions的元素列表,其中expressions是一?/span>expression数组Q其中的expression支持"div li.#id"形式
$$ҎQ只是简单的调用return Selector.findChildElements(document, $A(arguments))
虽然Selector有这么多ҎQ但是大部分都是内部调用的,我们一般都很少使用Q因为我们有个一个方便的Ҏ$$Q对于绝大部分情况已l够了
在写q个指南之前Q先介绍一?/span>Prototype主要是干吗的Q如果你比较xajax/javascipt斚w的应用,你应该早听说过q个 javascript framework?/span> Prototype是一个基?/span>javascript应用框架Q先引用一D官方网站的介绍
Prototype is a JavaScript framework that aims to ease development of dynamic web applications. Featuring a unique, easy-to-use toolkit for class-driven development and the nicest Ajax library around, Prototype is quickly becoming the codebase of choice for web application developers everywhere.
Ҏ作者自q介绍Q?/span>Prototype的目的是Z更方便的开?/span>javascript的应用,使用它可以更加方便简单的使用javascript~程Q开发出面向对象?/span>javascriptE序Q?/span>Prototype中包含包含了一个功能强大好用的ajax框架Q?/span>Prototype是一个基性的框架Q很多更高层ơ的框架都以它ؓ基础Q例?/span>scriptaculous效果?/span>
Prototype中包含一下几个部分:
base: Prototype中应用的基本功能Q基本上其他所有部分都依赖于它Q包括用于面向对象风格的Class.create?/span>Object.extendQ一?/span>Try对象Q函数绑定,number扩展Q?/span>PeriodicalExecuter(周期性执行某个函数的功能){?/span>
string: ?/span>String原型的扩展,?/span>stringd?/span>strip,escapeHTML{等好用的方?/span>
enumerable: 枚Dcd(array, hash, range{?/span>)的父cd象,提供枚Dcd的共同方?/span>
array: ?/span>Array原型的扩展,?/span>arrayd?/span>indexOf?/span>without{方?/span>
hash: ?/span>javascript提供了一个好用简单的Hash实现
range: l承?/span>enumerableQ一个范?/span>(例如3?/span>67)对象
ajax: 一个功能强大好用的ajax框架
dom: 对基于浏览器的开发提供了很好的跨览器封装,q添加很多强大的功能
selector: 提供了?/span>classQ?/span>css{选择元素的功?/span>
form: 关于表单的一些功?/span>
event: 单的夸^C件封?/span>
position: 提供了一些关于元素位|方面的功能
可以?/span>Prototype想一把瑞士军刀Qؓjavascipt装了很多通用的功能,大大化了javascript应用的开发,l?/span>javascript开发h员增M很大的信心,Prototype可以q行于以下^収ͼ使用它再也不用各U跨q_{问题烦g
* Microsoft Internet Explorer for Windows, version 6.0 and higher
* Mozilla Firefox 1.0/Mozilla 1.7 and higher
* Apple Safari 1.2 and higher
不过要注意的是:要想很好的理?/span>PrototypeQ应该首先理解一?/span>javascript面向对象开发的一些知识以后的文章对Prototype中具体的每个功能中的Ҏ做一个详l的介绍Q包括作用,实例{?/span>Prototype官方|站是:http://prototype.conio.net/ Q目前发布版q只?/span>1.4, 但是现在?/span>1.5已经发生了很大的变化Q而且很多Zprototype的库使用的都?/span>1.5的,所以强烈徏议通过svn下蝲最新版代码
base.js中包含下面的内容
cȝ创徏与承:
Class.create(): 创徏一个类Q例?/span> person=Class.create()
Object.extend(destination, source): ?/span>source中方法属?/span>copy?/span>destination(使用for property in source)Q需要注意的是,javascript中除了基本类?/span>(Number, Boolean)外都是引用类型,所以这U?/span>copy一般只?/span>copy引用而已Q?/span>destination?/span>sourceq是指向同一个方法或对象属?/span> (function array object)
在面向对象的~程中,一般通过Class.create新徏一个类Q如果这个类l承于另一个类Q一般?/span>Object.extend (class.prototype, parentClass.prototype)或?/span>Object.extend(class.prototype, aparentClassInstance)
Object构造函数的扩展Q?/span>
Object是其他对象实例的构造函?/span>(var a=new Object())Q也是所有其他类的父c,?/span>Object直接扩展(注意不是扩展Object.prototypeQ扩?/span> Object.prototype相当于添加实例方?/span>)相当于ؓObjectcL加静态方?/span>
Object.inspect(object): 调用object?/span>inspect(如果定义?/span>)?/span>toStringҎQ返回一个对象的字符串表C?/span>
Object.keys(object): q回一个对象的所有属性和Ҏ名称l成的数l?/span>, 例如Object.keys(document.body)
Object.values(object):q回一个对象的所有属性和Ҏ的值组成的数组, 例如Object.values(docuement)
Object.clone(object): q回一个对象的clone版本Q其实是执行Object.extentҎ?/span>object中的Ҏ属?/span>copyC个新对象中,然后q回q个对象
函数邦定Q?/font>
定义?/span>Function对象的两个方法,bind?/span>bindAsEventListenerQ这两个Ҏ是一个函数的两个ҎQ对?/span>java?/span>c#E序员来_看到q个也许感到很惊Ӟ因ؓ在他们看来函数只是一个程序语句组l结构而已?/span>>怎么q有ҎQ而且q可以扩展?q也?/span>javascript{脚本语a相对?/span>java{一个非常强大的功能Q函C是一个对象,函数名就是这个对象的名称Q只要你愿意Q你也可以?/span> new Function(…)来定义函敎ͼ所以ؓ函数定义Ҏ也就很正怸q了
q两个函数的主要作用是ؓ了解决?/span>javascript面向对象风格~程?/span>this的引用问题,?/span>javasctipt?/span>this关键字始l指向调用该函数的对象或者指向?/span>callQ?/span>applyҎ指定的对象(具体q方面的知识可以自己google一下,以下pd?/span>prototype的介l也假设读者对javascript语言比较熟悉了,如果不熟悉可以找?/span>javascript权威指南q本书看看)要理解这个问题首先要理解始终指向q个问题Q就?/span>thisq个关键字比较特D,不能把他当成一般的变量名看待,最常见的一个错误就是在q回函数的调用中使用thisQ例?/span>return function(){this.aMethod()}, 当你下次调用q个q回的匿名方法时Q这?/span>this引用的内容又指向了调用这个函数的对象了,C的一点的this是个关键字,不是变量名,不会产生闭包
?/span>Number的扩?/span>(注意num也可以看成对象,其实是在使用的时候系l自动打包成Number对象)Q?/span>
toColorPartQ把数字转换为可以用于表C?/span>color?/span>16q制|例如 7.toColorPart()=>"07"Q?/span>28.toColorPart()=>"1C"
succ: q回num++, 但不改变num本n的|其实是 return thisQ?/span>1
timesQ对?/span>0到这个数字轮调用一个函?/span>, 例如function a(n){docuement.write(n)}, 10.times(a), 显C?/span>012345678910, 注意函数也是一个对象,而且与其他对象ƈ没有实质的区?/span>
Try对象Q?/span> Try对象提供了一个很有趣的功?/span>, 先看一下如下的代码Q?/span>
var Ajax = {
getTransport: function() {
return Try.these(
function() {return new XMLHttpRequest()},
function() {return new ActiveXObject(’Msxml2.XMLHTTP’)},
function() {return new ActiveXObject(’Microsoft.XMLHTTP’)} )
|| false;
}
?/font>
Try对象提供了一个方?/span>these, q个Ҏ接受一个函数类型的参数列表Q然后轮执行这些函敎ͼ当其中一个函数没有生错误时Q就停止执行Qƈ且返回这个函数返回的|自己慢慢体会?/span>
PeriodicalExecuter(周期性执行器)对象
q个对象是对setIntervalҎ的简单封装,使用Ҏ如下
var a=new PeriodicalExecuter(callback, frequency ) Q其?/span>callback指要执行的函数名 frequency?/span>每次执行的时间间?/span>
要停止的话,调用q个对象?/span>stopҎ可以了 a.stop()
下面介绍Prototype?/span>String对象的扩展部分:
q部分主要ؓstring对象d了几个很有用的方?/span>:
strip(): L字符串两边的I白, 例如" jj ".strip()q回"jj"
stripTags()Q去掉字W串中的html标签
stripScripts(): L字符串中?/span>javascript代码D?/span>
extractScripts(): q回字符串中?/span>javascript代码Q返回数l?/span>
evalScripts(): 执行字符串中?/span>javascript代码
escapeHTML()Q将字符串中?/span>html代码转换为可以直接显C的格式, 例如?/span>< 转化?/span> < Q在ie6中有bugQ执行这个操作返回的字符Ԍ多个连在一LI白变成了一个,所以很多换行什么的都被L?/span>
unescapeHTML(): escapeHTML的反向过E?/span>
truncate(length, truncation): 截断Q例?/span>"abcdefghigkl".truncate(10)q回abcdefg…, truncation默认?/span>"…" toQueryParams(separator)/parseQuery(separator)Q将一?/span>querystring转化Z?/span>hash表(其实是一个对象,?/span>javascript中对象可以当?/span>hash表来用,因ؓ对象的属性或Ҏ可以通过object[propertyName]来访问)
toArray(): return this.split('’), 转化Z个字W数l?/span>
camelize(): ?/span>background-color的Ş式{化ؓbackgroundColor形式Q用?/span>style/css?/span>
capitalize(): q回一个首字母大写的字W串
inspect(useDoubleQuotes): q回字符串的表示形式, 例如"sdfj""sfa".inspect() q回“’sdfj"sfa’”
gsub(pattern, replacement)Q?/span>pattern是一个正则表辑ּQ?/span>replacement是一个函?/span>(或者是一?/span>template字符?/span>)Q对于字W串中每个匹?/span>pattern的部分?/span>replacement处理Q然后将 replacementq回的值将原来匚w的部分替换掉Q例?/span>"skdjfAsfdjkAdk".gsub(/A/,function(match) {return match[0].toLowerCase()}), 字W串所有的A转化?/span>a, 注意pattern中不要添?/span>g选项Q因?/span>gsub会递归的执?/span>matchҎ
sub(pattern, replacement, count) Q?/span>gsub的另一UŞ式,不过可以讄执行的次?/span>
scan(pattern, iterator): ?/span>gsub差不多,但是q回的是字符串本w,也就是说对于pattern中的每个匚w执行iteratorQ但是不q回替换的字W串"skdjfAsfdjkAdk".gsub(/A/,function(){alert have a A’})
underscore(): 'borderBottomWidth’.underscore() -> 'border_bottom_width’
dasherize(): 'Hello_World’.dasherize() -> 'Hello-World’
Template模板c:
使用ҎQ?/font>
var template = new Template(replacement, pattern);
template.evaluate(object) 有点?/span>php中的模板Q默?/span>(没有提供pattern)?/span>{propertyName}形式的东西替换了object的属性?/span>
Enumerable是一个抽象对象(需要说明的是,javascript中ƈ没有cȝ概念Q所指的cM是一个函敎ͼl承一般指的是一个对?/span>(?/span>)它的方法属?/span>copy(通过Object.extend, copy的是引用)到子c?/span>(函数)?/span>prototype属?/span>(一个对?/span>)中)
Enumerable不能直接使用Q它被很多枚丄型(Hash?/span>Array?/span>Range{)所l承Q承的cd都要实现一?/span>_eachҎQ提供具体类型的枚DҎ
Enumerable为其他子cL供了如下的方法:
each(iterator): iterator是一个函数对?/span>, q个Ҏ调用具体cd?/span>_eachҎ对自w包含的每个对象调用iteratorQ例如如?/span>Enumerable具体指的是一?/span>ArrayQ?/span>eg: var a=[2,3,4], ?/span>a.each(iterator)Ҏ依ơ调?/span>iterator(2,0) ,iterator(3,1), iterator(4,3)Q其中第二个参数指的是烦引。这个方法几乎在Enumerable中的每个Ҏ中都要用?/span>
eachSlice(number, iterator)Q将Enumerable cd对象每个每个按照number分开Q例?/span>[1,2,3,4,5].eachSlice(3)=>[[1,2,3],[4,5]], 没有提供iterator, ?/span>iterator=Prototype.K: function(k){return k}Q?/span>Prototype中的很多iterator默认值都是这个,或者是Prototype.emptyFunction: function() {},其实实际上返回的?/span>[iterator([1,2,3]),iterator([4,5])]
all(iterator): ?/span>Enumerablecd中的每个D?/span>iteratorQ如果其中有一个返?/span>falseQ则q回falseQ否则返?/span>trueQ相当于判断是否每个值执?/span>iterator都是"true"
any(iterator): ?/span>all相反Q判断是否每个值都?/span>"false"Q是否有一个值是trueQ?/span>
collect(iterator)/map: Ҏ个D?/span>iteratorQ将l果l成一个新的数l返?/span>
detect(iterator)/find: Ҏ个D?/span>iteratorQ如果有一个不?/span>falseQ则q回q个执行iterator后不?/span>false的?/span>(不是q回执行iterator后的?/span>)Q相当于扑ևW一个真?/span>
findAll(iterator)/select: 相当?/span>detect, 但是扑և所有的真|q回一个数l?/span>
grep(pattern, iterator)Q返回所以符?/span>pattern的|iterator提供的话Q则q回执行iterator的?/span>
include(object)/member: 数组中是否包?/span>object
inGroupsOf(number, fillWith): eachSlice的变异版本,按照number对象分开Q如果分开后的数组的最后一个值的length于number, 则用fillwith填充, 例如[1,2,3,4,5].inGroupsOf(3)=>[[1,2,3],[4,5,null]]
inject(memo, iterator): 注入
invoke(method): 调用
max(iterator): 最大?/span>
min(iterator): 最?/span>
partition(iterator): 分离
pluck(property): 采集
reject(iterator): 不合格的产品, ?/span>findAll相反
sortBy(iterator): Ҏiterator排序Q如果调用的对象?/span>Array的话Q直接调用内|的sort(iterator)p?/span>
toArray()/entries: 调用对象的每个值组成一个数l返?/span>
zip(): 例如[2,3,4].zip([5,6,7])=>[[2,5],[3,6],[4,7]], 如果最后一个参数类型ؓfunctionQ将q回[iterator([2,5]),iterator([3,6]),iterator([4,7])],
inspect(): Enumerable对象的字W串表示
$A = Array.from(iterable): ?/span>iterable转化为数l,如果iterable定义?/span>toArrayҎQ就调用q个ҎQ否则利?/span>iterable?/span>length属性进行枚?/span>, 如果iterable没有length属性的话就q回I数l?/span>[]
Array对象除了扩展Enumerable对象的方法外Q另外扩展了如下的几个方法,
注意以下Ҏ除了clear外都不改变原来数l,而是q回一个新数组Q?/span>
clear(): 清除数组Q利?/span>arr.length=0
first(): q回W一个元?/span>
last()Q返回最后一个元?/span>
compact(): 去除数组中gؓnull?/span>undefined的元?/span>
flatten(): 数l扁q_Q例?/span>[3,4,[6,7]]变ؓ[3,4,6,7]
without(): 去除指定的元?/span>, 可以指定多个?/span>, 例如[4,56,7,8].without(4,7) q回[56Q?/span>8]
indexOf(object): q回指定的元素在数组中的索引Q不包含则返?/span>-1
reverse(inline)Q?/span>Array内置函数reverse的增强,?/span>inline?/span>trueӞ跟内|的reverse函数效果一P改变原数l的|否则不改变原来的?/span>
reduce(): 如果数组只有一个元素,则返回这个元素,否则q回数组本n
uniq(): q回没有重复元素的数l?/span>
clone(): q回一个跟数组相同的数l,Array中的toArrayҎ覆盖?/span>Enumerable中的toArrayҎQ指向了q个Ҏ
inspect(): 跟数l的toStringҎcMQ返回对象的字符串表C,例如[2,3].inspect() q回 "[2,3]"
Hash对象(兌数组)?/span>Prototype新徏的一个对象,要创Z?/span>Hash对象可以调用$H(object)ҎQ用这个方法将生成一个基?/span> object对象?/span>Hash对象Q生成的Hash对象?/span>object的属性名作ؓkeyQ将object的属性值最为键|因ؓjavascript本n的特?/span>(对象本n是兌数组) Q所以实?/span>Hash也很单,Prototype中的Hash只是javascript的关联数l?/span>(对象)而已
Prototype中的Hash对象l承?/span>Enumerable对象Q所以也hEnumerable对象的所有属性和ҎQ另外它h以下的方法:
keys(): q回hash的键值数l?/span>
values(): q回值得数组
merge(hash): 合ƈ两个hash
toQueryString(): ?/span>string?/span>toQueryParamsҎxQ将hash转化Z?/span>querystring, 会调?/span>encodeURIComponent寚w和D行编?/span>
inspect(): hash的字W串表示
因ؓhash只是javascript的一个普通的对象而已Q所以添加一个键值对使用Q?/span> hash[key]=value可以了Q删除一个键值对使用 detele hash[key]可以了
Range对象是一个承自Enumerable?/span>"范围"对象Q你可以把它看成[x,x+1,x+2,x+3……x+n]的数l看待,但是比这L数组更节省存储空_因ؓrange对象只是保存x?/span>x+n而已
要创Z?/span>Range对象调用$R(start, end, exclusive) 函数可以了Q?/span>exclusive指定是否包含end本nQ如果没有指定或?/span>false则包?/span>endQ否则不包含,你可以利?/span>Enumerable中定义的Ҏ来操?/span>range对象Q?/span>range对象只是实现?/span>Enumerable对象需要的枚D逻辑_each和覆盖了includeҎ而已
Prototype中的ajax.js提供了一个非常好用的ajax框架Q一般应用中单的调用以下代码可以了
new Ajax.Request(
url, {method: “get”,
onSuccess: showFilter,
onFailure: function(request){alert(”Server error!”)},
onException: showError}
);
q个框架中提供了如下的对象和Ҏ{:
Ajax对象Q?/span>
只有一?/span>getTransportҎQ返回一?/span>XMLHttpRequest对象Q另外有一?/span>activeRequestCount属性,反映当前正在处理?/span>ajax数量
Ajax.Responders对象Q?/span>
l承?/span>EnumerableQ管理全局Ajax的请求,h如下Ҏ
register(responder)Q注册一个管?/span>ajaxh的对?/span>
unregister(responder)Q撤销一个管?/span>ajaxh的对?/span>
dispatch(callback, request, transport, json)Q触发注册的处理对象的方?/span>
q个对象一般很用,pȝ中已l用如下的代码注册了一个处理对?/font>
Ajax.Responders.register({
onCreate: function() {
Ajax.activeRequestCount++;
},
onComplete: function() {
Ajax.activeRequestCount–;
}
});
Ajax.Basec:
Ajax的基c?/span>, 只有一个方?/span>setOptions(options), 默认request参数如下Q你可以在新?/span>Ajax.request时指定:
method: 'post’,
asynchronous: true,
contentType: 'application/x-www-form-urlencoded’,
encoding: 'UTF-8′,
Ajax.Requestc:
ajax主要的类Q承自ajax.basec,客户端?/span> new Ajax.Request(url,options) 调用Q?/span>options是一个对?/span>(兌数组), ?/span>options中可以指?/span>methodQ?/span>asynchronousQ?/span>contentTypeQ?/span>encodingQ?/span>parametersQ?/span> postBodyQ?/span>username,password{选项Q其?/span>parameters可以是字W传或者关联数l象Q?/span>
另外?/span>options中还可以通过requestHeaders指定request headsQ其?/span>requestHeaders可以是数l?/span>(例如[”Connection”,”Close”,”aheadkey”,”aheadvalue”])或一个关联数l;
options中最重要的选项是指定ajax的回调方法,可以定义onComplete, onSuccess, onFailure, onException(执行q程中发生异常调用的ҎQ主要ؓonComplete, onSuccess, onFailure{回调方法生的)Q甚臛_以定?/span>on404,on503q样的回调方法,它们的参Cؓ(transport, json),其中transport求的XMLHttpRequest对象, json?/span>evalJSON的结?/span>
如果q回的是一?/span>javascript文g(Ҏq回?/span>Content-type头判?/span>)会执行evalResponseҎQ另?/span>Ajax.Request对象q有一?/span>evalJSONҎQ取得文件的时候就会执?/span>
q个对象的方法列表如下:
request(url) : 发送请求,new的时候就已经调用了,所以一般不需要?/span>
success(): 判断request是否成功?/span>
getHeader(name)Q根?/span>name得到request head
evalJSON(): 执行getHeader(”X-JSON”),q返回结?/span>
evalResponse(): 执行q回?/span>responseTextq返?/span>
Ajax.Updaterc?/span>:
l承?/span>Ajax.RequestQ只是比Ajax.Request增加了更?/span>html元素的功能,一般用方法是new Ajax.Updater(element, url, options), element可以是一个元素,也可以是{success:e1,failure:e2}q种形式,
默认情况下不会执行返回结果中?/span>javascriptQ如果你先执行,你可以指?/span>options中的evalScripts?/span>true
默认情况下是替换指定元素的内容,如果你希望是dQ可以指?/span>options?/span>insertion参数, insertion是一?/span>Insertion.Before?/span>Insertion.Top?/span>Insertion.Bottom?/span> Insertion.After(在dom.js中介l?/span>)
Ajax.PeriodicalUpdaterc?/span>:
l承?/span>Ajax.BaseQ周期性的更新一?/span>html元素的内容,q个cM调用Ajax.Updater?/span>html元素q行周期性的更新Q用方法ؓnew Ajax.PeriodicalUpdater(container, url, options), 参数?/span>Ajax.Updater差不多,其中options可以讄frequency(默认?/span>2)Q?/span>decayQ?/span>decay指的是当h的内Ҏ有变化的时候,frequency需要g长的倍数Q默认是1Q例如如?/span>decay设ؓ2Q?/span>frequency设ؓ3而内容一直没有变化,则请求的旉依次会变?/span> 3,6,12,24{?/span>
start(): 开始更?/span>, 初始化的时候会自动调用
stop(): 停止更新