﻿

介绍

PROTOTYPE 1.5.1 RC1

API文档

欢迎使用Prototype API文档。左边的栏目包含的是主要条目。当您选择这些条目时，它的详细内容就会在本栏显示出来。

我们正在尽最大的努力给你提供一个最新的、清晰的、示例非富的文档。这个文档的目标是让你能感受到温暖、迷惑等与我们在用prototype时一样的感觉。

这个API文档是一个参考文档。如果你需要学习怎样使用Prototype或者想了解特定属性方面的知识，你可以看看相关的条目。你可以在每一页的上面的访问它('提示与教程'链接)，并且也与橙色条相链接，在每个参考页面上都有。

享受这篇文档吧！

关于这个文件

这个API文档重新格式化过的，与原始的在线的文档 www.prototypejs.org/api 已经有一些不同了。

这个文件是经过编译的，由 Kjell Bublitz维护、标记

最后更新: 2007年3月20日

下载、更多的文档和新闻：

www.prototypejs.org

中文翻译：www.ruby-china.cn 站长

www.ruby-china.cn 站长
Prototype API 1.5.0 - prototypejs.org


Prototype中文导航

  • 介绍
  • 常用工具
    • getElementsByClassName
    • $
    • $A
    • $R
    • Try.these
    • $$
    • $F
    • $w
    • $H
  • 模块
    • Enumerable
      • any
      • collect
      • max
      • min
      • include
      • sortBy
      • toArray
      • find
      • select
      • map
      • reject
      • inject
      • size
      • partition
      • entries
      • findAll
      • all
      • detect
      • member
      • zip
      • each
      • grep
      • invoke
    • PeriodicalExecuter
    • Event
      • unloadCache
      • stop
      • observe
      • stopObserving
      • isLeftClick
      • findElement
      • pointerY
      • element
      • pointerX
    • ObjectRange
      • include
    • Hash
      • each
      • values
      • toQueryString
      • merge
      • remove
      • keys
      • inspect
    • Ajax
      • Ajax.Options
      • Ajax.PeriodicalUpdater
      • Ajax.Responders
      • Ajax.Updater
      • Ajax.Request
    • Function
      • bind
      • bindAsEventListener
    • Number
      • succ
      • times
      • toColorPart
      • toPaddedString
    • Element
      • pluck
      • previous
      • replace
      • getDimensions
      • previousSiblings
      • inspect
      • observe
      • hasClassName
      • scrollTo
      • remove
      • descendantOf
      • extend
      • up
      • removeClassName
      • recursivelyCollect
      • toggle
      • show
      • hasAttribute
      • next
      • setStyle
      • addMethods
      • makePositioned
      • siblings
      • immediateDescendants
      • hide
      • nextSiblings
      • toggleClassName
      • getHeight
      • getElementsBySelector
      • down
      • stopObserving
      • undoPositioned
      • makeClipping
      • ancestors
      • getStyle
      • cleanWhitespace
      • readAttribute
      • getElementsByClassName
      • empty
      • visible
      • match
      • undoClipping
      • descendants
      • update
      • Simulated
      • addClassName
      • getWidth
    • Form
      • Element
        • getValue
        • active
        • serialize
        • enable
        • clear
        • disable
        • Element
        • present
        • select
        • focus
      • serialize
      • getInputs
      • serializeElements
      • disable
      • reset
      • findFirstElement
      • focusFirstElement
      • request
      • getElements
      • enable
    • Position
    • Class
      • create
    • Prototype
    • Object
      • values
      • clone
      • toJSON(1.5.1)
      • inspect
      • extend
      • keys
    • String
    • TimeObserver
    • Insertion
      • Insertion
      • Bottom
      • Top
      • Before
      • After
    • Template
    • Date
      • toJSON
    • Array
      • first
      • clear
      • compact
      • toArray
      • toJSON
      • uniq
      • reverse
      • size
      • reduce
      • inspect
      • without
      • from
      • last
      • clone
      • each
      • flatten
      • indexOf
    • module


模块

API概要
  • Ajax—Prototype提供了三个对象来处理Ajax通讯
  • Array—Prototype扩展了所有的原生数组，提供了很多有用的方法
  • Class—Prototype对象是基本于类的OOP
  • Date—原生Date对象的扩展
  • Element—Element对象支持一些非常实用的DOM方法
  • Enumerable—Enumerable提供了大量有用的方法用以枚举
  • Event—Prototype使不同平台的事件处理变得更加流畅
  • Form—Form是一个名字空间，也是一个所有Form相关的事件的模块
  • Form.Element—这是一个用于辅助处理表单控件的方法集合
  • Function—Prototype扩展它只有一个目的：绑定
  • Hash—一个让哈希工作的方便工具的集合
  • Insertion—Insertion提供了一个动态插入HTML的跨浏览器解决方法
  • Number—Prototype扩展它是为了提供ObjectRange和类似Ruby的数字循环
  • Object—Object被Prototype当成是一个名字空间，也就是说，它只是把一些新的方法一起放起来
  • ObjectRange—ObjectRange与Enumerable混用，让范围变得很灵活
  • PeriodicalExecuter—这是一个很简单的让一个函数定期执行的办法
  • Position—Position对象提供了一系列的办法帮助元素进行定位和布局
  • Prototype—Prototype名字空间提供了基本的Prototype库的信息
  • String—Prototype增强了的String，有很多有用的方法论
  • Template—Template提供了一个很简单、漂亮的办法创建HTML小元件
  • TimedObserver—可以被用来定期检查某些值，然后触发一个回调过程


Ajax.Options

这个部分详细描述了核心的选项(所有的Ajax请求相同)和回调函数。

在Ajax名字空间里，所有的请求对象共享一个相同的选项与回调函数集。回调函数在请求的生命周期的不同阶段被调用，并且总是用同一参数例表。它们与其它选项是一起被传给请求的。

通用选项
选项 | 默认值 | 描述
asynchronous | true | 确定XMLHttp是不是异步调用。由于同步的使用非常不成熟，往往没有好的结果，所以你应该避免使用。切记！
contentType | 'application/x-ww-form-urlencoded' | 你请求的头的Content-Type。你可能想发送XML而不是常规的URL-encoded的格式，在这种情况下，你必须修改它。
encoding | 'UTF-8' | 你请求内容的编码。最好不要动它。如果奇怪的编码问题发生，你可能不得不修改他，让他与你的页面与服务器的编码能取得一致。
method | 'post' | 请求的HTTP方法。另一个广泛使用的方法是'get'。作为一个Ruby On Rails的特别产物，Prototype还对其它的动词作出反应(如：'put'和'delete')，通过实际上的'post'然后在原始的请求方法上加一个额外的'_method'参数。
parameters '' 请求的参数。 在用GET方法时，它会被编码成URL-encoded，其它方法时，它会被放到请求数据里面。这既可以是一个URL-encoded的字符串，也可以是任何Hash兼容的对象(实际上是任何东西)， 它的属性代表着参数。
postBody | None | 在'post'方法(实际的方法，可能会有一些转化，我们在上面的method选项中已经说明了)时为请求体定义内容。如果没有定义，那么parameters的内容就会替代它。
requestHeaders 看说明 请求头能用两种方式进行传送：
  • 作为对象，用属性代表头
  • 作为数组，(0,2...)偶数索引的作为头名，(1,3...)奇数索引的作为值
Prototype自动提供了一组默认头。但这些头可以修改或者增强：
  • X-Request-With设置成了"XMLHttpRequest"。
  • X-Prototype-Version提供了当前的Prototype的版本(比如：1.5.0)。
  • Accept默认是'text/javascript, text/html, application/xml, text/xml, */*'
  • Content-Type是基于contentType(译者：注意大小写)和编码选项建立的。
通用的回调函数

在独立的实例上使用时，除onException外的所有的回调都会被调用并传入两个参数：XMLHttpRequest对象和X-JSON响应头的求值的结果(如果有的话，可以是为null)。他们也执行与这个引用相关的请求对象(如:Ajax.Request)的内容。

另外的一种时间顺序的描述以及那些回调是互斥的，请查看Ajax.Request。

选项 | 描述
onComplete | 在请求生命周期的最后被调用，一旦请求结束，状态相关的函数就会被调用，然后可能的自动的行为就被处理。
onException | 在XHR错误发生时被调用。有一个习惯的标志：第一个参数是这个请求本身(例如：Ajax.Request)，第二个是异常对象
onFailure | 当一个请求结束，并且它的状态码存在，但是不是2XY系列时，它会被调用。如果有返回码相关的回调函数已经定义了，这个函数就会被忽略。它发生在onComplete之前。
onInteractive | (不保证可用的回调)每次请求接收到一部分的回应时被调用(但不是最后的部分)，因为返回可能是多次发送到达的。
onLoaded | (不保证可用的回调)一旦XHR对象被创建，连接打开，准备发送真实的请求时，它就会被调用。
onLoading | (不保证可用的回调)当XHR对象正在创建，并且连接已经打开。
onSuccess | 当请求完成，并且返回的状态是2XY的，或者没有返回状态码。如果有返回码相关的回调函数已经定义了，这个函数就会被忽略。它发生在onComplete之前。
onUninitialized | (不保证可用的回调)在XHR对象刚创立时被调用。
onXYZ | XYZ表示返回的HTTP状态码。当请求结果并且返回的状态码与我们用的回调函数名是一样的时候，它就会被调用。并阻止了onSuccess/onFailure的执行。发生在onComplete之前
响应回调

一个只能响应可用的回调，而不是对单个Ajax请求对象。

当在响应中被使用时，所有的除了onException和onCreate外的回调都有三个参数：请求者(例如：Ajax.Request)、XMLHTTPRequest对象和X-JSON响应头的求值的结果，(如果有的话，可以是为null)。他们也执行与这个引用相关的请求对象(如:Ajax.Request)的内容。

选项 | 描述
onCreate | 不管什么时候一个请求对象在Ajax的名字空间里被创建时，它就会被调用，在它的参数调整之后，在它的XHR连接打开之前。它接收两个参数：请求对象和XHR对象。


Ajax.PeriodicalUpdater

new Ajax.PeriodicalUpdater(container, url[, options])定期的执行一个Ajax请求，然后更新基于反回文本的容器内容。提供了一个“衰退”的机制，在返回内容没有变化时会引起一定的更新时长的变化。

这个对象着重于对定时更新的一般需求，用于各类"轮询"机制(如：在线聊天或者在线邮件系统)。

基本的思路就是在一个规定时间段运行一个规定的Ajax.Updater ，如果decay选项(见下面)是激活的，那么还要监视返回文本的变化。

更多的选项

Ajax.PeriodicalUpdater支持所有的通用的选项和回调函数，以及由Ajax.Updater增加的部分。它自己还提供了两个新的选项来处理原始的时间段和它的衰减率(火箭专家怎么做让我们会觉得更合理？)。

选项 | 默认 | 描述
frequencey | 2 | 这不是频率(象：0.5Hz)的意思，而是一个时间(象多少秒)。它是Ajax请求的最小间隔时间。你不要把它变的太短(否则你可能会得到多个请求同时发起的情况，如果请求的处理与返回花的时间更长的话)，但是技术上你可以提供一个小于1的值，比如0.75秒
decay | 1 | 它控制在返回不变的时候请求时间的增长率。它就象是当前时间段(最初值由frequency参数指定)的乘法器。第次请求返回相同的数据时，当前的时间段就会被decay乘积。因为默认值表示规则的请求(即不改变请求时长)。如果值比1大就会导致间隔时长的增加。少于1的值是危险的：返回内容相同的时间越长，你的检测就越频繁，直到这个时长短到你的浏览器除了自杀外没有别的办法为止。需要注意的是，只要返回文本的内容已经变化，那么当前的时长就会变重新设置回最初的值。

为了更好的理解decay，下面给出了一个小例子：

new Ajax.PeriodicalUpdater('items', '/items', {
method: 'get', frequency: 3, decay: 2
});
调用号 | 什么时间? | Decay之前 | 返回变化? | Decay之后 | 下个时段 | 说明
1 | 00:00 | 2 | n/a | 1 | 3 | 返回肯定是变化的，因为之前没有返回。
2 | 00:03 | 1 | yes | 1 | 3 | 返回的确改变了：我们“重置”成1，实际上已经是1。
3 | 00:06 | 1 | no | 3 | 6 | 返回没有变化：decay根据decay选项的因子增大。我们将等更长的时间。
4 | 00:12 | 2 | no | 4 | 12 | 还没有变化，再增加一倍。
5 | 00:24 | 4 | no | 8 | 24 | 天，这个东西还会变化吗？
6 | 00:48 | 8 | yes | 1 | 3 | 哈，终于变了！重新设置成1，又重新使用最初的时长。
禁用或者重新启用PeriodicalUpdater

你可以很方便的调用它的stop方法来停止PeriodicalUpdater。如果你想重新启用它，只要调用它的start方法就可以了。两个方法都不带参数。

注意！不是特例！

Ajax.PeriodicalUpdater并不是一个Ajax.Updater的一个特例，虽然它们的名字上象。所以在用它的时候，你不要指望你能使用常用的由Ajax.Request提供的和从Ajax.Updater继承的方法，比如evalJSON或者getHeader。同样onComplete也在这里被劫持，为更新管理所用；如果你想被每个成功的请求通知到，你要用onSuccess来代替(注意：它在update执行前被调用)。


Ajax.Request

new Ajax.Request(url[, options])初始化和处理一个Ajax请求。

这个对象是一个通用的Ajax请求：它处理请求的整个过程，处理确定的文件，允许你插入你需要的回调函数。

在可选项哈希里，你通常需要提供一个onComplete和/或onSuccess回调。除非你遇到小概率事情，你接收到的返回是javascript类型的，而这个类型是会被自动执行的。

详尽的通用选项和回调函数，参看Ajax.Options。

创建一个请求者的唯一正确的办法就是用new操作符。只要对象一创建，它就会开始请求，然后就开始在它整个生命周期内处理这个请求。

一个基本的例子
URL = 'http://www.google.com/search?q=Prototype';
new Ajax.Request('/proxy?url=' + encodeURIComponent(URL), {
method: 'get',
onSuccess: function(transport) {
var notice = $('notice');
if (transport.responseText.match(/<a class=l href="http:\/\/prototypejs.org/))
notice.update('Yeah!  You are in the Top 10!').setStyle({
background: '#dfd' });
else
notice.update('Damn!  You are beyond #10...').setStyle({
background: '#fdd' });
}
});
请求生命周期

在我们这个优美的请求对象下面，当然是XMLHttpRequest。定义的生命周期是这样的：

  1. 创建
  2. 初始化
  3. 请求的发送
  4. 接收返回(可能会发生很多次，根据包的返回次数来决定)
  5. 返回接收成功，请求结束

你可以看到在Ajax选项里，Prototype的Ajax对象定义了很多的回调函数，这些函数按下面的顺序被调用：

  1. onCreate(这个实际上一个给Ajax全局反应者保留的回调函数)
  2. onUninitialized(Created的映象)
  3. onLoading(initialized的映象)
  4. onLoaded(对发送的Request的映象)
  5. onInteractive(对接收到的Response的映象)
  6. onXYZ(数字返回的状态码)，onSuccess或者onFailure(看下面)
  7. onComplete

最下面的两步都是对Response接收的映象，但是它们的顺序还是这样的。如果一个确定状态的回调函数定义了，它就会被调用。否则如果 onSuccess定义了并且返回已经是成功了(见下面)，那么它也会被调用。否则，如果onFailure定义了并且没有成功，那么它就会被调用。只有在这些可能被首先调用的函数调用之后，onComplete才会被调用。

一个通用性的提示

根据你的浏览器对XMLHttpRequest的实现情况，一个或者多个的回调可能永远也不会被调用。特别是onLoaded和onInteractive目前还不是100%的可靠的。但是全局的onCreate、onUnitialized和最后两步是可以得到非常好的保证的。

onSuccess和onFailure，正在使用的回调

太多的人习惯于使用Ajax.Requester与最原始的XMLHttpRequest一样去用，即使他们只关心“成功”的返回，他们也只定义一个onComplete回调，然后手动测试:

// This is too bad, there's better!
new Ajax.Requester('/your/url', {
onComplete: function(transport) {
if (200 == transport.status)
// yada yada yada
}
});

首先，将在下面讲到，在没有返回状态或者没有“2xy”返回状态(201是一个成功的状态)时，你可以使用更好的“成功”检测：成功通常是定义的、HTTP智慧的。看下边的示例

其次，你可以完全免除一起对状态的检测！Prototype增加了对于成功与失败的特定的回调函数，在上面我们已经列举了。如果你只对成功感兴趣，下面展示了你可以这样做。例如：

new Ajax.Requester('/your/url', {
onSuccess: function(transport) {
// yada yada yada
}
});
自动的javascript返回求值

任何返回的MIME的类型不明或者是javascript相关的将会被自动的传到eval。在你大叫这对安全是一个多么大的违背之前，请记住XHR通常只能用在同一个主机上的URL上(这就是有名的同源策略(Same Origin Policy 或 SOP)：这些脚本默认在你的控制之下的。。

这意味着，你不用提供一个回调来处理一个纯的javascript的Ajax返回。这非常的酷，不是吗？会在prototype里被处理的javascript相关的MIME类型如下:

  • application/ecmascript
  • application/javascript
  • application/x-ecmascript
  • application/x-javascript
  • text/ecmascript
  • text/javascript
  • text/x-ecmascript
  • text/x-javascript

这些MIME类型字符串是以大小写不敏感的方式被检测的。

可能会有用的方法

Requester对象在你的回函数函数里提供了几个非常方便的方法，特别是当你的请求结束时。由于所有的本地回调都是在requester的环境下执行的，所以你可以使用把这些方法使用在你的回调函数中。

返回是成功的吗？

success()方法检查XHR的状态属性，并且遵守通过的HTTP指示：未知的状态认为是成功的，是全部的2XY状态码家族里的一个。相对于经常用的测试200==transport.status的办法，这通常是一个比较好的办法测试你的返回。

得到HTTP返回头

虽然你可以通过XHR对象的getResponseHeader得到返回的头，但是这会让代码显的有一些冗长，并且不少实现在头找不到的情况下会引起一个异常。为了让这个过程处理方便，你可以使用getHeader方法，它代替了上面冗长的版本并且在异常出现在时返回null。

new Ajax.Requester('/your/url', {
onSuccess: function() {
// Note how we brace against null values
if ((this.getHeader('Server') || '').match(/Apache/))
++gApacheCount;
// Remainder of the code
}
});
JSON头的计算

有些后台返回JSON不是作为返回文本，而是用了X-JSON的头。你可以通过evalJSON直接计算它的内容并得到结果，如果没有这个头或者内容无效，它会返回null。为了健壮，头的内容在计算之前被括号包起来了。

你实际上甚至不用自己调用这些方法，因为Prototype自动会调用这个方法并且把结果当成是最后的参数传送给任何一个回调函数(除了onCreate)。所以下面的代码不是最佳的:

new Ajax.Request('/your/url', {
onSuccess: function() {
var json = this.evalJSON(); // Uselessly evals a second time!
// Remainder of the code
}
});

这是我们推荐的

new Ajax.Request('/your/url', {
onSuccess: function(transport, json) {
// Remainder of the code
}
});


Ajax.Responders

Ajax.Responders.register(responder)
Ajax.Responders.unregister(responder) 是一个全局侦听者的仓库，对于每一步基于Prototype的Ajax请求，都会被通知到。

有时候你需要提供对于所有的Ajax动作在页面内的发生情况的一个通用的方法(在Ajax.Request，Ajax.Updater或者Ajax.PeriodicalUpdater)。

比如，你可能想自动的显示一个指示，如果你的Ajax请求正在执行，然后在结束时关掉这个指示。你也可能也想把异常的处理也考虑进去，然后把这些记录在页面的某个地方。或者等等的许多种可能。

为了实现这个，Prototype提供了Ajax.Responders，它让你注册(如果你愿意，你也可以注销)各种正确命名的方法对象作为响应者。这些回调函数的名字是常规的，这样你的响应者就能执行任何你感兴趣的部分。

例如，Prototype能自动的注册一个响应者，然后维护着一个很好用的变量：Ajax.activeRequestCount。这个值在任何时候都是存在的，它是当前活动的Ajax请求的总数(当然是那些用Prototype创建的) ，这是通过监视onCreate和onComplete事件实现的。代码相当的简单：

Ajax.Responders.register({
 onCreate: function() {
   Ajax.activeRequestCount++;
 },
onComplete: function() {
  Ajax.activeRequestCount--;
 }
});

所有的回调在生命周期内都是可以得到的；事实上onCreate只能被响应者得到，因为对于每个的请求都能得到看起不可思议：你已经知道了它什么时候创建，不是吗？ 它在XHR连接打开之前就创建了，这个事情刚好是在onUninitialized之前发生。

注销(Unregister):记得这个引用

常通，注销某些东西，就要求你使用与注册时相同的东西。所以，如果你计划注销一个响应者，你要先定义它，然后把它传给register，最后，传给unregister。


Ajax.Updater

new Ajax.Updater(container, url[, options])执行一个Ajax请求，并且基于返回的文本进行容器的更新。

Ajax.Updater是一个Ajax.Request的特例：对于Request适用的对于Updater都适用。如果你对Ajax.Request不熟悉，先看一下关于它的文档，然后再回来看这一部分。

一个简单的示例
new Ajax.Updater('items', '/items', {
  parameters: { text: $F('text') }
});
定时的注意点

在更新发生后，onComplete回调会被执行。

更多的选项

由于Ajax.Updater的目标是用Ajax请求返回的文本来更新特定的DOM元素(容器)的内容，所以它除了有一些常规的选项外，还有一些新的属性选项。他们是：

选项 | 默认值 | 描述
evalScripts | false | 这个选项决定<script>元素是不是要留下来(并且由浏览器执行)或者不留下。
insertion | None | 默认是Element.update，它会用返回文本直接替换容器的所有的内容。你也可能想要插入返回文本到已有的内容中。你只要传入一个有效的Insertion对象就可以了，比如：Insertion.Bottom。

在下面的例子中，我们假设要创建一个新元素，这个元素是通过Ajax返回的XHTML片段来创建的，而我们要把这个元素加到一个列表容器里面，但是要把它放到容器内容的最下面。那么按下面的做：

new Ajax.Updater('items', '/items', {
parameters: { text: $F('text') },
insertion: Insertion.Bottom
});
就一个容器，还是要有成功/失败的选择？

上面的例子总是认为你要更新一个容器，不管是成功还是失败。很多时候你可能并不想这样。你可能想只在成功时更新它，而在失败时更新另外一个容器。

为了实现这个目标，你可以传入一个对象而不是DOM元素作为容器的参数。这个对象必须有一个成功的属性(即容器)，而它就是成功的请求后容器要更新的内容。如果你同时提供了一个失败的属性(即容器)，那么它就会被容器用来在失败时更新。

下面的代码里，只有成功的请求被更新：

new Ajax.Updater({ success: 'items' }, '/items', {
 parameters: { text: $F('text') },
 insertion: Insertion.Bottom
});

下面的例子假设失败后会显示一个错误消息作为返回文本，并且用这个返回文本来更新另外一个元素(可能是一个状态区)。

new Ajax.Updater({ success: 'items', failure: 'notice' }, '/items', {
 parameters: { text: $F('text') },
 insertion: Insertion.Bottom
});


Ajax

Prototype提供了三个对象来处理Ajax的通讯，我们在下面给出了一个列表。有了Prototype，用Ajax技术就非常简单了！所有的三个对象使用共同的选项集，我们将会分别的进行讨论。

下面的文章提供了几个例子。

模块索引
Ajax选项

这个部分详细描述了核心的选项(所有的Ajax请求相同)和回调函数。

Ajax.PeriodicalUpdater
new Ajax.PeriodicalUpdater(container, url[, options])

定期的执行一个Ajax请求，然后更新基于反回文本的容器内容。提供了一个“衰退”的机制，在返回内容没有变化时会引起一定的更新时长的变化。

Ajax.Request
new Ajax.Request(url[, options])

初始化和处理一个Ajax请求。

Ajax.Responders
Ajax.Responders.register(responder)
Ajax.Responders.unregister(responder)

是一个全局侦听者的仓库，对于每一步基于Prototype的Ajax请求，都会被通知到。

Ajax.Updater
new Ajax.Updater(container, url[, options])

执行一个Ajax请求，并且基于返回的文本进行容器的更新。


clear::Array

clear() -> Array 清空数组。

示例
var guys = ['Sam', 'Justin', 'Andrew', 'Dan'];

guys.clear();
// -> []
guys
// -> []


clone::Array

clone() -> newArray 返回一个复制的数据，保持原来的数据不变化。

示例
var fruits = ['Apples', 'Oranges'];

var myFavs = fruits.clone();
myFavs.pop();

// fruits -> ['Apples', 'Oranges']
// myFavs -> ['Apples']


compact::Array

compact() -> newArray 返回一个新的数组，但不再包含null/undefine的值。

示例
['frank', , 'sue', , 'sally', null].compact()

// -> ['frank', 'sue', 'sally']


Array

Prototype对原生的Javascript代码扩展了很多功能强大的方法。

它是通过下面两种方法实现：

  • 它把Enumerable混进来，而Enumerable本身就有很多方法了。
  • 增强了很多额外的方法，我们在这个部分将会讲解。

在Prototype里，数组不再是我们原来使用的那个无足轻重的对象了，不再是那个只允许我们使用它的长度与下标运算符[]的对象了。它们变成了非常强大的对象，对于使用它们的99%的事例中都会有很明显的代码简化作用。

在本页将要阐述：
  • 为什么你要停止使用for...in
  • 开发者应该怎样做？
  • 性能上的注意
  • 模块索引
为什么我们要停止使用for...in来做遍历(或者永远不拿起来)

不少javascript的开发者被误导在数组元素里去使用for...in这样的javascript结构。这样的代码在Prototype里将不会工作。

你可能知道ECMA 262标准，它定义了ECMAScript第三版，并且期望所有的主流浏览器都能支持，包括MSIE。它定义了很多的关于Array($15.4.4)的方法，包括了concat，join，pop和push。命名了，但是这十个函数中只有少数方法有详细的描述。

这个标准同时明确定义了for...in结构($12.6.4)用于对象的属性的枚举，对象写在关键字in的右边。只有属性明确标记成非枚举的才会被这个循环省略。默认情况下，prototype与它的长度属性都是这样标记的，以防止使用for...in来枚举数组的方法。这很容易导致开发者把for...in当成是一个索引循环的快捷方法，而这并不是他实际的目的。

然后，Prototype并没有办法把它加入到Array.prototype的方法标记成非枚举的。因为，在使用Prototype的情况下对数组使用for...in也会枚举所有的扩展的方法，包括来自Enumerable模块和Prototype加进的Ajax名字空间的(将在这部分讨论，下面将会列出来)。

开发者应该怎样做？

你可以使用最原始的循环：

for (var index = 0;
index < myArray.length; ++index) {
var item = myArray[index];
// Your code working on item here...
}

或者你可以使用迭代子，比如each：

myArray.each(function(item) {
 // Your code working on item here...
});

这个副作用更加说明了for...in的真正用处， 而不是它是一个负担：正如你将看到的，大部分的循环可以很方便的使用Ajax的新方法或者嵌入的Enumerable模块。所以手工的循环应该是非常少的。

情能上的注意

假设你有一个非常大的数组，使用需要语法闭包(也就是传送给迭代子的匿名函数，在每个循环时都被调用)的迭代子，象each或者依靠重复数组的构造(比如uniq)，将会导致不满意的恨性能问题。在这种情况下，你最好手工写循环，但是你要小心的缓存好长度属性以及对前缀++运算符的使用：

// Custom loop with cached length property: maximum full-loop performance on very large arrays!
for (var index = 0, len = myArray.length; index < len; ++index) {
 var item = myArray[index];
 // Your code working on item here...
}
模块索引
clear
clear() -> Array

清空数组。

clone
clone() -> newArray

返回一个复制的数据，保持原来的数据不变化。

compact
compact() -> newArray

返回一个新的数组，但不再包含null/undefine的值。

each
each(iterator) -> Array

从小的索引值开始增加的对数组的迭代。

first
first() -> value

返回数组里的第一个元素，如果数组是空的，则返回undefined。

flatten
flatten() -> newArray

返回一个“平”(一维)数组，内嵌的数组递归的被加上"inline"。例如，在处理一个递归的集合算法的结果中，这个就会非常有用。

from
Array.from(iterable) -> actualArray

克隆一个已经存在的数组或者从一个类似数组的集合中新建一个数组。是$A()的别名，详情与实例参考$A()的页面。

indexOf
indexOf(Value) -> postion

返回数组中第一个参数出现的位置。如果找不到，返回-1。

inspect
inspect() -> String

返回面向调试的数组的字符串表示。

last
last() -> value

返回数组里的最后一个元素。数组为空，返回undefined。

reduce
reduce() -> Array | singleValue

数组缩减：一个元素的数组直接返回这个元素，多个元素的数组保持不变。

reverse
reverse([inline = true]) -> Array

返回一个倒置的数组。默认是对原数组的倒置。如果inline设备为false，那么会复制一个数组后做倒置，这样原数组就不会被破坏。

size
size() -> Number

返回数组的大小。

toArray
toArray() -> newArray

这是一个本地的、优化的来自Enumerable的、并与它混合后的toArray。

toJSON(1.5.1)
toJSON -> String

返回一个JSON字符串。

uniq
uniq -> newArray

产生一个没有重复的版本。如果没有重复的，数组保持不变返回。

without
without(value...) -> newArray

产生一个新的版本，不包含value指定的值。


each::Array

each(iterator) -> Array从小的索引值开始增加的对数组的迭代。

实际上each方法就是混合进来的Enumerable模块方法。

这是主要是强调它的执行的顺序。

参考

Enumerable


first::Array

first() -> value返回数组里的第一个元素，如果数组是空的，则返回undefined。

示例
['Ruby','Php', 'Python'].first()
// -> 'Ruby'

[].first()
// -> undefined


flatten::Array

flatten() -> newArray返回一个“平”(一维)数组，内嵌的数组递归的被加上"inline"。例如，在处理一个递归的集合算法的结果中，这个就会非常有用。

示例
['frank', ['bob', 'lisa'], ['jill', ['tom', 'sally']]].flatten()

// -> ['frank', 'bob', 'lisa', 'jill', 'tom', 'sally']


from::Array

Array.from(iterable) -> actualArray克隆一个已经存在的数组或者从一个类似数组的集合中新建一个数组。是$A()的别名，详情与实例参考$A()的页面。

这个$A()方法的一个别名。到这个方法相应的页面可以查看完整的示例与说明。

参考

$A 方法


indexOf::Array

indexOf(Value) -> postion返回数组中第一个参数出现的位置。如果找不到，返回-1。

注意：这里使用==等价运算符，而不是严格的相等运算符。下面的例子中将会展示了这个。

小的提示：这个方法使用了平常的老的优化的索引循环，所以没有扩展被检测到的风险。

示例
[3, 5, 6, 1, 20].indexOf(1)
// -> 3

[3, 5, 6, 1, 20].indexOf(90)
// -> 1

[0, false, 15].indexOf(false)
// -> 0 instead of 1, because 0 == false!


inspect::Array

inspect() -> String返回面向调试的数组的字符串表示。

更多的关于inspect的信息，参看Object.inspect。

示例
['Apples', {good: 'yes', bad: 'no'}, 3, 34].inspect()

// -> "['Apples', [object Object], 3, 34]"
注意

如果你只是想简单的把数组里的字符串联接起来，用原生的联接方法替代：

['apples', 'bananas', 'kiwis'].join(', ')
// -> 'apples, bananas, kiwis'


last::Array

last() -> value返回数组里的最后一个元素。数组为空，返回undefined。

示例
['Ruby', 'Php', 'Python'].last()

// -> 'Python'

[].last()
// -> undefined


reduce::Array

reduce() -> Array | singleValue数组缩减：一个元素的数组直接返回这个元素，多个元素的数组保持不变。

示例
[3].reduce()
// -> 3

[3, 5].last()
// -> [3, 5]


reverse::Array

reverse([inline = true]) -> Array返回一个倒置的数组。默认是对原数组的倒置。如果inline设备为false，那么会复制一个数组后做倒置，这样原数组就不会被破坏。

示例
var nums = [3, 5, 6, 1, 20];

nums.reverse(false)
// -> [20, 1, 6, 5, 3]
nums
// -> [3, 5, 6, 1, 20]

nums.reverse()
// -> [20, 1, 6, 5, 3]
nums
// -> [20, 1, 6, 5, 3]


size::Array

size() -> Number返回数组的大小。

这是对从Enumerable混入的size方法的本地优化，它避免了数组的克隆。它使用的是数组原生的length属性。


toArray::Array

toArray() -> newArray这是一个本地的、优化的来自Enumerable的、并与它混合后的toArray。

这个版本的toArray是clone的一个别名。它避免了默认的迭代行为。

参见

Array.clone()


toJSON(1.5.1)::Array

toJSON -> String返回一个JSON字符串。

示例
['a', {b: null}].toJSON();
//-> '["a",{"b":null}]'


uniq::Array

uniq -> newArray产生一个没有重复的版本。如果没有重复的，数组保持不变返回。

示例
['Sam', 'Justin', 'Andrew', 'Dan', 'Sam'].uniq();
// -> ['Sam', 'Justin', 'Andrew', 'Dan']

['Prototype', 'prototype'].uniq();
// -> ['Prototype', 'prototype'] because String comparison is case-sensitive
性能提示

在重复的大数组中，这个方法潜在的大的性能代价：

  • 因为它没有要求数组被排序，这样就会产生二个数量级的复杂性。
  • 因为它依告了javascript里的Array.concat，每次碰到新的值(在结果中不存在的)的时间就会产生一个新的、临时的数组。

实现可以设计的更加高效。

有优化后的提交地实现的话，这个页面会及时更新。


without::Array

without(value...) -> newArray产生一个新的版本，不包含value指定的值。

示例
[3, 5, 6, 1, 20].without(3)
// -> [5, 6, 1, 20]

[3, 5, 6, 1, 20].without(20, 6)
// -> [3, 5, 1]


create::Class

create() -> Function返回一个与Ruby类功能相似的函数。

Class.create()返回一个函数，当它被调用时，它会调用它自己的initialize的方法。这样就会使它更强是Ruby的OOP。这样，通过覆盖父类的构造函数，让你更加容易的子类化。

示例
var Animal = Class.create();
Animal.prototype = {
 initialize: function(name, sound) {
  this.name = name;
  this.sound = sound;
 },

 speak: function() {
  alert(name + " says: " + sound + "!");
 }
};
var snake = new Animal("Ringneck", "hissssssssss");
snake.speak();
// -> alerts "Ringneck says: hissssssssss!"

var Dog = Class.create();

Dog.prototype = Object.extend(new Animal(), {
 initialize: function(name) {
  this.name = name;
  this.sound = "woof";
  }
 });
var fido = new Dog("Fido");
fido.speak();
// -> alerts "Fido says: woof!"


Class

Prototype实现基于类的OOP的对象。

目前，继承通过Object.extend来实现。

模块索引
create
create() -> Function

返回一个与Ruby类功能相似的函数。


Date

模块索引
toJSON
toJSON() -> String

把日期转化成JSON字符串(根据ISO的格式)。


toJSON::Date

toJSON() -> String把日期转化成JSON字符串(根据ISO的格式)。

示例
new Date(1969, 11, 31, 19).toJSON();
//-> '"1969-12-31T19:00:00"'


addClassName::Element

addClassName(element, className) -> HTMLElement 添加一个CSS类到元素上。

示例

<div id="mutsu" class="apple fruit"></div>

$('mutsu').addClassName('food')

$('mutsu').className
// -> 'apple fruit food'
$('mutsu').classNames()
// -> ['apple', 'fruit', 'food']


addMethods:: Element

addMethods([methods]) 接收一个方法哈希，然后把它们变成是扩展元素的方法以及这个Eelement对象的方法。

Element.addMethods使得你在Element对象里添加你自己的方法成为可能，并在以后作为扩展元素(由$()工具返回的)的方法使用或者作为Element的方法。

$(element).myOwnMethod([args...]);

注意这样也能工作：

Element.myOwnMethod(element|id[, args...]);

你只需要简单地传给Element.addMethods一个方法的哈希，新的方法就会被增加上去。要注意的是任何一个方法的第一个参数是element。在每个方法里面，记得把element传给$()然后再返回它为适当的时候能够进行方法连接准备。

你的哈希应该是这样的：

var myVeryOwnElementMethods = {
  myFirstMethod: function(element[, args...]){
    element = $(element);
    // do something
    return element;
  },

  mySecondMethod: function(element[, args...]){
    element = $(element);
    // do something else
    return element;
  }
};

最后一个警告：Element.addMethods有一个内建的安全机制，防止你重写原先的元素方法或者属性(比如象getAttribute或者innerHTML)，但是没有任何事情阻止你改写Prototype的方法。所以注意你的每一个步骤。

示例

想要一个干净、语义标记，但是还要一个额外的div包围在你的元素周围？为什么不创建一个wrap('tagName')的Element方法，让它包装这个元素到tagName元素中并返回这个包装元素(即新的tagName元素)。

Element.addMethods({
  wrap: function(element, tagName) {
    element = $(element);
    var wrapper = document.createElement('tagName');
    element.parentNode.replaceChild(wrapper, element);
    wrapper.appendChild(element);
    return Element.extend(wrapper);
  }
});

这个方法你可以这样用：

// Before:
<p id="first">Some content...</p>

$(element).wrap('div');
// -> HTMLElement (div)

// After:
<div><p id="first">Some content...</p></div>

当你经过认真的考虑确定你的wrap()方法返回的是新创建的<div>时，准备感谢Element.extend的时间到了，你可以立即给它链上一个新的方法：

$(element).wrap('div').setStyle({backgroundImage: 'url(images/rounded-corner-top-left.png) top left'});

你在你的WEB应用中经常使用Ajax.Updater更新DOM元素吗？你想要一个快速的、漂亮的减少你的代码量的办法吗？试试这个：

Element.addMethods({
  ajaxUpdate: function(element, url, options){
  element = $(element);
  element.update('<img src="/images/spinner.gif" alt="loading..." />');
  new Ajax.Updater(element, url, options);
  return element;
  }
});

现在，不管什么时候你想更新这个元素的内容，你只要这样做：

$(element).ajaxUpdate('/new/content');
// -> HTMLElement

这个方法首先把元素的内容替换成漂亮的旋转的Ajax活动指示。然后创建一个Ajax.Updater，并由这个Ajax.Updater将请求结果更新到元素内容上，删除原来旋转的活动指示。

在没有参数的情况下使用Element.addMethods

这是Element.addMethods最后一个无耻的小秘密。你可以没有传入参数调用它。那这样会发生什么呢？它只是在所有的Element.Methods、Element.Methods.Simulated、Form.Methods和Form.Element.Methods进行迭代并且把它们增加给相应的元素(Form.Methods只能加给form元素，而Form.Element.Methods则加给input、select和textarea这些元素)。

那些什么时候有用呢？

想象一下你想增加一个方法让提交按钮失效并用象“请等待...”这样的字来替代它。当然你不想让所有的元素都包含这个方法，是吧？那么下面就是你怎样让这件事可以运行：

Form.Element.Methods.processing = function(element, text) {
  element = $(element);
  if (element.tagName.toLowerCase() == 'input' ['button', 'submit'].include(element.type))
    element.value = typeof text == 'undefined' ? 'Please wait...' : text;
  return element.disable();
};

Element.addMethods();


ancestors::Element

ancestors(element) -> [HTMLElement...] 收集所有的元素祖先，将它们作为扩展元素的数组返回。

返回数组的第一个元素是element的直接祖先(它的parentNode)，第二个是那的祖父，依次类推，直到到达html元素。所以html总是这个数组的最后一个元素。除非你显式的查找它的祖先。但是你又不喜欢这样做，不是吗？

注意所有的Prototype的DOM遍历方法都会忽略文字节点，并只返回元素节点。

示例

<html>
[…]
<body>
<div id="father">
<div id="kid">
</div>
</div>
</body>
</html>

$('kid').ancestors();
// -> [div#father, body, html] // Keep in mind that
// the `body` and `html` elements will also be included!
document.getElementsByTagName('html')[0].ancestors();
// -> []


cleanWhiteSpace::Element

cleanWhitespace(element) -> HTMLElement 删除所有的只含空白字符的字符节点。返回当前元素。

cleanWhitespace()删除只有空格的文字节点。当在使用nextSibling、previousSibling、firstChild和lastChild来遍历DOM是非常有用

如果你只要访问元素节点(并且不是文本节点),你可以试一下Element的新的up()、down()、netx()和previous()方法。你肯定会满意。

示例

观察下面的HTML片段：

<ul id="apples">
<li>Mutsu</li>
<li>McIntosh</li>
<li>Ida Red</li>
</ul>

让我们打个赌那个是第一个列表项：

var element = $('apples');
element.firstChild.innerHTML;
// -> undefined

看起来似乎并不是我们想要的结果。为什么呢？ul#apples的第一个孩子实际上是在<ul id="apples">和<li>Mutsu</li>中间的只带了空白的文本节。

我们删除这个没有用的空白：

element.cleanWhitespace();

我们的DOM现在看起来是这样的了：

<UL id="apples"><LI>Mutsu</LI><LI>McIntosh</LI><LI>Ida Red</LI></UL>

现在firstChild跟我们期望的一样了。

element.firstChild.innerHTML;
// -> 'Mutsu'


Element

Element对象引入了令人激动的功能强大的DOM方法，你可以把它当成是一个Element的方法进行调用(当然这已经相当过时了)或者扩展后的元素的方法(这个归功能Element.extend加入的语法新特性)。

在你继续之前，你的确应该读一下“How Prototype extends the DOM(Prototype怎样扩展DOM)”这篇文章，它将带你了解Prototype魔幻的DOM扩展机制神秘的内部工作原理。

内容导航
  • 示例
  • 模块索引
示例

<div id="message" class=""></div>

$('message').addClassName('read'); // Toggle the CSS class name of div#message
// -> div#message

Element.toggleClassName('message', 'read'); // You could also use a syntactic-sugar-free version:
// -> div#message

由于大部分的Element方法返回它们应用到的元素本身，所以你可以把方法这样链起来：

$('message').addClassName('read').update('I read this message!').setStyle({opacity: 0.5});

这不就是美吗？

模块索引
addClassName
addClassName(element, className) -> HTMLElement

添加一个CSS类到元素上。

addMethods
addMethods([methods])

接收一个方法哈希，然后把它们变成是扩展元素的方法以及这个Eelement对象的方法。

ancestors
ancestors(element) -> [HTMLElement...]

收集所有的元素祖先，将它们作为扩展元素的数组返回。

classNames
classNames(element) -> [className...]

返回一个新的类名实例，用一个Enumerable对象来读写元素的类名。

cleanWhiteSpace
cleanWhitespace(element) -> HTMLElement

删除所有的只含空白字符的字符节点。返回当前元素。

descendantOf
descendantOf(element, ancestor) -> Boolean

检查元素是不是ancestor的后代。

descendants
descendants(element) -> [HTMLElement...]

收集所有的元素子孙，将它们作为扩展元素的数组返回。

down
down(element[, cssRule][, index = 0]) -> HTMLElement | undefined

返回元素的第一个符合CSS规则的子孙(如果index指定为n，返回第n个子孙)。如果没有CSS规则指定，所有的子孙都会被加入。如果没有子孙满足条件，返回undefined。

empty
empty(element) -> Boolean

测试元素是否为空(比如只包含空格)。

extend
extend(element)

把所有的Element.Methods和Element.Methods.Simulated的方法扩展到element上面。如果element是一个input、textarea、select的标签，它也会被扩展上Form.Element.Methods的方法。如果它是form标签，它会被扩展上Form.Methods。

getDimensions
getDimensions(element) -> {height: Number, width: Number}

找到元素的宽度与高度并返回一个按键/值的成对方式组合成的对象。

getElementsByClassName
getElementsByClassName(element, className) -> [HTMLElement...]

取出所有是className这上CSS类的element的后代，并且组织成一个扩展的元素数组来返回。

getElementsBySelector
getElementsBySelector(element, selector...) -> [HTMLElement...]

传入任意数量的CSS选择器(字符串)，返回一个根据文档顺序组织的扩展过的成功匹配的element的孩子数组。

getHeight
getHeight(element) -> Number

查找并返回计算后的元素高度。

getStyle
getStyle(element, property) -> String | null

返回一个元素的给定CSS属性。属性可以是CSS本身的方式或者是驼峰式的。

getWidth
getWidth(element) -> Number

查找并返回计算后的元素宽度。

hasClassName
hasClassName(element, className) -> Boolean

检查元素是否有给定的CSS类名。

hide
hide(element) -> HTMLElement

隐藏并返回element。

immediateDescendants
immediateDescendants(element) -> [HTMLElement...]

收集所有的元素的直接后代(既孩子)，并将它们当成扩展元素的数组返回。

inspect
inspect(element) -> String

返回面向调试的元素的字符串表示。

makeClipping
makeClipping(element) -> HTMLElement

通过给element的overflow设置"hidden"值来模拟支持的比较差的CSS块属性，返回element本身。

makePositioned
makePositioned(element) -> HTMLElement

提供了一个方便的办法创建一个CSS容器块，通过把元素CSS的position值设置成'relative'，不管它的初始position是'static'还是undefined。返回element本身。

match
match(element, selector) -> Boolean

检查元素是不是与给定的CSS选择器匹配。

next
next(element[, cssRule][, index = 0]) -> HTMLElement | undefined

返回元素的匹配CSS规则的下一个兄弟(或者index指定的)。如果没有CSS规则，那么返回全部后面的兄弟。如果没有匹配的兄弟，返回undefined。

nextSiblings
nextSiblings(element) -> [HTMLElement...]

收集元素后面的所有的兄弟元素，将它们组织成扩展元素的数组返回。

observe
observe(element, eventName, handler[, useCapture = false]) -> HTMLElement

注册一个事件处理函数到element上，并返回这个element。

previous
previous(element[, cssRule][, index = 0]) -> HTMLElement | undefined

返回元素的匹配CSS规则的前一个兄弟(或者index指定的)。如果没有CSS规则，那么返回全部前面的兄弟。如果没有匹配的兄弟，返回undefined。

previousSiblings
previousSiblings(element) -> [HTMLElement...]

收集元素前面的所有的兄弟元素，将它们组织成扩展元素的数组返回。

readAttribute
readAttribute(element, attribute) -> String | null

返回元素的属性值，如果属性没有指定，返回null。

recursivelyCollect
recursivelyCollect(element, property) -> [HTMLElement...]

递归的收集由属性指定的关系的元素。属性只能是一个指向单个DOM节点的元素的属性。返回一个由扩展元素组成的数组。

remove
remove(element) -> HTMLElement

从document里完全删除element并返回它。

removeClassName
removeClassName(element, className) -> HTMLElement

删除元素的CSS类名并返回它。

replace
replace(element[, html]) -> HTMLElement

用html的内容来替换element，返回被删除的element。

scrollTo
scrollTo(element) -> HTMLElement

卷动窗口让元素显示在视口的顶部，返回这个元素。

setStyle
setStyle(element, styles) -> HTMLElement

修改元素的CSS风格属性。styles是按属性-值对这样的哈希形式传入的，并且属性是按驼峰式指定的。

show
show(element) -> HTMLElement

显然并返回元素。

siblings
siblings(element) -> [HTMLElement...]

收集所有的兄弟元素，以扩展元素的数组返回。

stopObserving
stopObserving(element, eventName, handler) -> HTMLElement

注销处理函数，并且返回元素。

toggle
toggle(element) -> HTMLElement

切换元素的可视性。

toggleClassName
toggleClassName(element, className) -> HTMLElement

切换元素的CSS类名并返回。

undoClipping
undoClipping(element) -> HTMLElement

将元素makeClipping()之前的overflow的值恢复。并返回它。

undoPositioned
undoPositioned(element) -> HTMLElement

把元素原来放回makePositioned()之前的位置，并返回它。

up
up([cssRule][, index = 0]) -> HTMLElement | undefined

返回元素匹配cssRule的第一个祖先(或者index指定的祖先)。如果cssRule没有给出，所有的祖先都会被考虑。如果没有祖先匹配要求，那么返回undefined。

update
update(element[, newContent]) -> HTMLElement

将元素的内容替换成newContent并返回元素。

visible
visible(element) -> Boolean

返回一个布尔值表示元素是否可见(例如：是不是行内风格的属性被设置成"display:none")。


descendantOf::Element

descendantOf(element, ancestor) -> Boolean 检查元素是不是ancestor的后代。

由于descendantOf()内部会将$()应用到ancestor，它可以接受一个元素或者元素的ID作为第二个参数。

示例

<div id="australopithecus">
<div id="homo-herectus">
<div id="homo-sapiens"></div>
</div>
</div>

$('homo-sapiens').descendantOf('australopithecus');
// -> true

$('homo-herectus').descendantOf('homo-sapiens');
// -> false


descendants::Element

descendants(element) -> [HTMLElement...] 收集所有的元素子孙，将它们作为扩展元素的数组返回。

注意所有的Prototype的DOM遍历方法忽略文本节点并只返回元素节点。

示例

<div id="australopithecus">
<div id="homo-herectus">
<div id="homo-neanderthalensis"></div>
<div id="homo-sapiens"></div>
</div>
</div>

$('australopithecus').descendants();
// -> [div#homo-herectus, div#homo-neanderthalensis, div#homo-sapiens]

$('homo-sapiens').descendants();
// -> []


down::Element

down(element[, cssRule][, index = 0]) -> HTMLElement | undefined 返回元素的第一个符合CSS规则的子孙(如果index指定为n，返回第n个子孙)。如果没有CSS规则指定，所有的子孙都会被加入。如果没有子孙满足条件，返回undefined。

down()方法是终极的DOM遍历工具的一部分(查看up()、next()、previous()体会Prototype的风格的优美)。它允许准确的基于索引或基于CSS规则的对任何元素后代的选择。

由于它忽略文本节点(它只返回元素)，所以你不用担心空白节点。

作为一个额外的奖励，所有的返回元素已经被扩展了。所以我们可以对它进行链式的使用：

$(element).down(1).next('li', 2).hide();

遍历DOM从来没有这么容易过！

参数

如果没有传入参数，方法就会返回第一个孩子(与调用firstChild类似，但是down()返回一个已经扩展的元素。

如果index传入，元素的相应的后代就会被返回。(这与从descendants()返回的元素数组里选择一个元素是一样的。注意第一个元素的索引是0。

如果cssRule定义了，那么down()将返回匹配的第一个孩子。这是一个从一个列表中取得第一个元素的丰常好的方法。比如传入'li'作为方法的第一个参数。

如果cssRule与index都指定，那么down()首先收集所有与指定的CSS规则匹配的孩子，然后返回与指定的index对应的孩子。

上述所有情况中，如果没有找到对应的孩子，那么会返回undefined。

示例

<ul id="fruits">
<li id="apples">
<ul>
<li id="golden-delicious">Golden Delicious</li>
<li id="mutsu" class="yummy">Mutsu</li>
<li id="mcintosh" class="yummy">McIntosh</li>
<li id="ida-red">Ida Red</li>
</ul>
</li>
</ul>

$('fruits').down();
// equivalent:
$('fruits').down(0);
// -> li#apple

$('fruits').down(3);
// -> li#golden-delicious

$('apples').down('li');
// -> li#golden-delicious

$('apples').down('li.yummy');
// -> li#mutsu

$('fruits').down('.yummy', 1);
// -> li#mcintosh

$('fruits').down(99);
// -> undefined
参看

Element：up | previous | next


empty::Element

empty(element) -> Boolean 测试元素是否为空(比如只包含空格)。

示例

<div id="wallet"> </div>
<div id="cart">full!</div>

$('wallet').empty();
// -> true

$('cart').empty();
// -> false


extend::Element

extend(element) 把所有的Element.Methods和Element.Methods.Simulated的方法扩展到element上面。如果element是一个input、textarea、select的标签，它也会被扩展上Form.Element.Methods的方法。如果它是form标签，它会被扩展上Form.Methods。

这里是魔法产生的的地方。

通过Prototype的自定义方法扩展元素，我们可以享受到我们所渴望的语法的甜头与使用的方便。例如我们可以对扩展后的元素进行如下操作：

element.update('hello world');

由于大部分的Element方法返回它们操作的element本身，所以你可以这样链接它们：

element.update('hello world').addClassName('greeting');

需要注意的是所有的Element方法返回的元素都是扩展的(即使是象Element.siblings这些方法那样返回的元素数组)并且Prototype的旗舰常用工具方法$()和$$()显然也返回扩展的元素。

想更多的了解Prototype怎样扩展DOM，请参看这篇文章。


getHeight::Element

getHeight(element) -> Number 查找并返回计算后的元素高度。

这个方法返回那些display已经被设置成none值的，不管是inline规则的还是一个CSS样式表上的正确值。由于性能原因，如果你想到得到元素的宽度与高度时，你应该考虑使用getDemension()。

示例

<div id="rectangle" style="font-size: 10px; width: 20em; height: 10em"></div>

$('rectangle').getHeight();
// -> 100

注意

所有的返回都是数字值，虽然它们表示的是象素。


getHeight::Element

getStyle(element, property) -> String | null返回一个元素的给定CSS属性。属性可以是CSS本身的方式或者是驼峰式的。

这个方法查找元素的CSS属性，究竟它是应用了inline的还是样式表。它在不同的浏览器下并不一致，包括float、opacity(返回0表示完全透明，1表示完全不透明)、定位属性和隐藏元素的尺度(宽度或者高度)。

示例

$(element).getStyle('font-size');
// equivalent:

$(element).getStyle('fontSize');
// -> '12px'

注意

Internet Explorer返回字面值，而其它浏览器返回计算后的值。

考虑下面的HTML片段：

<style>
#test {
font-size: 12px;
margin-left: 1em;
}
</style>
<div id="test"></div>

$('test').getStyle('margin-left');
// -> '1em' in Internet Explorer,
// -> '12px' elsewhere.

Safari对任何非inline的属性返回null，如果元素已经被隐藏(display被设置成'none')。

并非所有的CSS属性都支持。

你可能只能使用DOM等级2的样式规定。


getWidth::Element

getWidth(element) -> Number 查找并返回计算后的元素宽度。

这个方法返回那些display已经被设置成none值的，不管是inline规则的还是一个CSS样式表上的正确值。由于性能原因，如果你想到得到元素的宽度与高度时，你应该考虑使用getDemension()。

示例

<div id="rectangle" style="font-size: 10px; width: 20em; height: 10em"></div>

$('rectangle').getWidth();
// -> 200

注意

所有的返回都是数字值，虽然它们表示的是象素。


hasAttribute::Element

hasAttribute(element, attribute) -> Boolean在没有的浏览器(IE6/7)里模拟标准DOM方法hasAttribute

注意

<a id="link" href="http://prototypejs.org">Prototype</a>

$('link').hasAttribute('href');
// -> true


hasClassName::Element

hasClassName(element, className) -> Boolean 检查元素是否有给定的CSS类名。

示例

<div id="mutsu" class="apple fruit food"></div>

$('mutsu').hasClassName('fruit');
// -> true

$('mutsu').hasClassName('vegetable');
// -> false


hide::Element

hide(element) -> HTMLElement隐藏并返回element。

示例

<div id="error-message"></div>

$('error-message').hide();
// -> HTMLElement (and hides div#error-message)

向后兼容的改变

在以前的版本里，你可以传入任意数量的元素到Element.toggle，Element.show和Element.hide里，为了统一起见，1.5版本上不再有效！

但是你可以通过使用Enumerable来达到类似的结果：

['content', 'navigation', 'footer'].each(Element.hide);

// -> ['content', 'navigation', 'footer']
// and displays #content, #navigation and #footer.

或者更好的：

$('content', 'navigation', 'footer').invoke('hide');

// -> [HTMLElement, HTMLElement, HTMLElement] (#content, #navigation and #footer)
// and displays #content, #navigation and #footer.

参看

Enumerable：invoke | each


immediateDescendants::Element

immediateDescendants(element) -> [HTMLElement...]收集所有的元素的直接后代(既孩子)，并将它们当成扩展元素的数组返回。

返回的数组反映了孩子在文档的顺序(例如：索引为0的元素是第一个最上面的孩子)。

注意所有的Prototype的DOM遍历方法忽略文本节点并只返回元素节点。

示例

<div id="australopithecus">
<div id="homo-herectus">
<div id="homo-neanderthalensis"></div>
<div id="homo-sapiens"></div>
</div>
</div>

$('australopithecus').immediateDescendants();
// -> [div#homo-herectus]

$('homo-herectus').immediateDescendants();
// -> [div#homo-neanderthalensis, div#homo-sapiens]

$('homo-sapiens').immediateDescendants();
// -> []


inspect::Element

inspect(element) -> String返回面向调试的元素的字符串表示。

更多的关于inspect的信息，参考Object.inspect

示例

<ul>
<li id="golden-delicious">Golden Delicious</li>
<li id="mutsu" class="yummy apple">Mutsu</li>
<li id="mcintosh" class="yummy">McIntosh</li>
<li</li>
</ul>

$('golden-delicious').inspect();
// -> '<li id="golden-delicious">'

$('mutsu').inspect();
// -> '<li id="mutsu" class="yummy apple">'

$('mutsu').next().inspect();
// -> '<li>'


makeClipping::Element

makeClipping(element) -> HTMLElement通过给element的overflow设置"hidden"值来模拟支持的比较差的CSS块属性，返回element本身。

使用undoClipping()可以取消这个操作。

元素可见的区域是由元素的宽度与高度决定的。

示例

<div id="framer">
<img src="/assets/2007/1/14/chairs.jpg" alt="example" />
</div>

$('framer').makeClipping().setStyle({width: '100px', height: '100px'});
// -> HTMLElement

参看

Element： undoClipping | setStyle


makePositioned::Element

makePositioned(element) -> HTMLElement提供了一个方便的办法创建一个CSS容器块，通过把元素CSS的position值设置成'relative'，不管它的初始position是'static'还是undefined。返回element本身。

使用undoPositioned()可以取消这个操作。

示例

<p>lorem […]</p>
<div id="container">
<div id="element" style="position: absolute; top: 20px; left: 20px;"></div>
</div>

让div#element的定位相对于它的父节点。

$('container').makePositioned();
// -> HTMLElement

参看

Element：undoPositioned


match::Element

match(element, selector) -> Boolean检查元素是不是与给定的CSS选择器匹配。

示例

<ul id="fruits">
<li id="apples">
<ul>
<li id="golden-delicious">Golden Delicious</li>
<li id="mutsu" class="yummy">Mutsu</li>
<li id="mcintosh" class="yummy">McIntosh</li>
<li id="ida-red">Ida Red</li>
</ul>
</li>
</ul>

$('fruits').match('ul');
// -> true

$('mcintosh').match('li#mcintosh.yummy');
// -> true

$('fruits').match('p');
// -> false


next::Element

next(element[, cssRule][, index = 0]) -> HTMLElement | undefined返回元素的匹配CSS规则的下一个兄弟(或者index指定的)。如果没有CSS规则，那么返回全部后面的兄弟。如果没有匹配的兄弟，返回undefined。

next()方法是终极的DOM遍历工具的一部分(查看up()、down()、previous()体会Prototype的风格的优美)。它允许准确的基于索引或基于CSS规则的对任何元素随后的兄弟的选择。(注意两个兄弟元素是指他们有共同的父亲，head与body元素是兄弟，因为他们有html这个父亲。)

由于它忽略文本节点(它只返回元素)，所以你不用担心空白节点。

作为一个额外的奖励，所有的返回元素已经被扩展了。所以我们可以对它进行链式的使用：

$(element).down(1).next('li', 2).hide();

遍历DOM从来没有这么容易过！

参数

如果没有传入参数，方法就会返回第一个兄弟(与调用nextSibling类似，但是next()返回一个已经扩展的元素。)。

如果index传入，元素的相应的兄弟就会被返回。(这与从nextSiblings()返回的元素数组里选择一个元素是一样的。注意第一个元素的索引是0。

如果cssRule定义了，那么next()将返回匹配的第一个兄弟。

如果cssRule与index都指定，那么next()首先收集所有与指定的CSS规则匹配的元素，然后返回与指定的index对应的兄弟。

上述所有情况中，如果没有找到对应的后面的兄弟，那么会返回undefined。

示例

<ul id="fruits">
<li id="apples">
<h3>Apples</h3>
<ul id="list-of-apples">
<li id="golden-delicious" class="yummy">Golden
Delicious</li>
<li id="mutsu" class="yummy">Mutsu</li>
<li id="mcintosh">McIntosh</li>
<li id="ida-red">Ida Red</li>
</ul>
<p id="saying">An apple a day keeps the doctor away.</p>
</li>
</ul>

$('list-of-apples').next();
// equivalent:
$('list-of-apples').next(0);
// -> p#sayings

$('title').next(1);
// -> ul#list-of-apples

$('title').next('p');
// -> p#sayings

$('golden-delicious').next('.yummy');
// -> li#mcintosh

$('golden-delicious').next('.yummy', 1);
// -> li#ida-red

$('ida-red').next();
// -> undefined

参看

Element：up | down | previous


nextSiblings::Element

nextSiblings(element) -> [HTMLElement...]收集元素后面的所有的兄弟元素，将它们组织成扩展元素的数组返回。

兄弟是指具有相同的父亲的元素。所以象head与body元素就是兄弟，他们的父亲是html元素。随后的兄弟是指文档中接在element下面的那些元素。

返回的数组反映兄弟元素在文档中的顺序(比较索引为0表示靠近element的下一个兄弟)。

注意的是Prototype的DOM遍历忽略文本节点并且只返回元素节点。

示例

<ul>
<li id="golden-delicious">Golden Delicious</li>
<li id="mutsu">Mutsu</li>
<li id="mcintosh">McIntosh</li>
<li id="ida-red">Ida Red</li>
</ul>

$('mutsu').nextSiblings();
// -> [li#mcintosh, li#ida-red]

$('ida-red').nextSiblings();
// -> []


observe::Element

observe(element, eventName, handler[, useCapture = false]) -> HTMLElement 注册一个事件处理函数到element上，并返回这个element。

示例

$(element).observe('click', function(event){
alert(Event.element(event).innerHTML);
});
// -> HTMLElement (and will display an alert dialog containing
// element's innerHTML when element is clicked).


pluck::Enumerable

pluck(propertyName) -> Array对collect的优化：取得相同的属性。返回属性的值。

由它避免了对于匿名函数(就象你用collect一样)语法闭包的开销，这个性能上更好。或者更重要的是，它让代码更加简洁易懂。

示例

['hello', 'world', 'this', 'is',
'nice'].pluck('length')
// -> [5, 5, 4, 3, 4]

document.getElementsByClassName('superfluous').pluck('tagName').sort().uniq()
// -> sorted list of unique canonical tag names for elements with this
// specific CSS class...

参看

invoke方法用于调用函数，功能相同。


previous::Element

previous(element[, cssRule][, index = 0]) -> HTMLElement | undefined返回元素的匹配CSS规则的前一个兄弟(或者index指定的)。如果没有CSS规则，那么返回全部前面的兄弟。如果没有匹配的兄弟，返回undefined。

previous()方法是终极的DOM遍历工具的一部分(查看up()、down()、next()体会Prototype的风格的优美)。它允许准确的基于索引或基于CSS规则的对任何元素之前的兄弟的选择。(注意两个兄弟元素是指他们有共同的父亲，head与body元素是兄弟，因为他们有html这个父亲。)

由于它忽略文本节点(它只返回元素)，所以你不用担心空白节点。

作为一个额外的奖励，所有的返回元素已经被扩展了。所以我们可以对它进行链式的使用：

$(element).down(1).next('li', 2).hide();

遍历DOM从来没有这么容易过！

参数

如果没有传入参数，方法就会返回第一个兄弟(与调用previousSibling类似，但是previous()返回一个已经扩展的元素。

如果index传入，元素的相应的兄弟就会被返回。(这与从previousSiblings()返回的元素数组里选择一个元素是一样的。注意第一个元素的索引是0。

如果cssRule定义了，那么preivous()将返回匹配的第一个兄弟。

如果cssRule与index都指定，那么preivous()首先收集所有与指定的CSS规则匹配的元素，然后返回与指定的index对应的兄弟。

上述所有情况中，如果没有找到对应前面的兄弟，那么会返回undefined。

示例

<ul id="fruits">
<li id="apples">
<h3>Apples</h3>
<ul id="list-of-apples">
<li id="golden-delicious" class="yummy">Golden
Delicious</li>
<li id="mutsu" class="yummy">Mutsu</li>
<li id="mcintosh">McIntosh</li>
<li id="ida-red">Ida Red</li>
</ul>
<p id="saying">An apple a day keeps the doctor away.</p>
</li>
</ul>

$('saying').previous();
// equivalent:
$('saying').previous(0);
// -> ul#list-of-apples

$('saying').previous(1);
// -> h3

$('saying').previous('h3');
// -> h3

$('ida-red').previous('.yummy');
// -> li#mutsu

$('ida-red').previous('.yummy', 1);
// -> li#golden-delicious

$('ida-red').previous(5);
// -> undefined

参看

Element：up | down | next


previousSiblings::Element

previousSiblings(element) -> [HTMLElement...]收集元素前面的所有的兄弟元素，将它们组织成扩展元素的数组返回。

兄弟是指具有相同的父亲的元素。所以象head与body元素就是兄弟，他们的父亲是html元素。前面的兄弟是指文档中接在element前面的那些元素。

返回的数组反映兄弟元素在文档中的相反顺序(比较索引为0表示靠近element的下一个兄弟)。

注意的是Prototype的DOM遍历忽略文本节点并且只返回元素节点。

示例

<ul>
<li id="golden-delicious">Golden Delicious</li>
<li id="mutsu">Mutsu</li>
<li id="mcintosh">McIntosh</li>
<li id="ida-red">Ida Red</li>
</ul>

$('mcintosh').previousSiblings();
// -> [li#mutsu, li#golden-delicious]

$('golden-delicious').previousSiblings();
// -> []


readAttribute::Element

readAttribute(element, attribute) -> String | null返回元素的属性值，如果属性没有指定，返回null。

这个方法提供了两个目的。首先他作为一个简单的getAttribute容器，在Safari和IE(比如：它没有.apply或者.call)。其次它清理IE在处理属性时造成的可怕的混乱。

示例

<a id="tag" href="/tags/prototype" rel="tag" title="view related bookmarks." my_widget="some info.">Prototype</a>

$('tag').readAttribute('href');
// -> '/tags/prototype'

$('tag').readAttribute('title');
// -> 'view related bookmarks.'

$('tag').readAttribute('my_widget');
// -> 'some info.'


recursivelyCollect::Element

recursivelyCollect(element, property) -> [HTMLElement...]递归的收集由属性指定的关系的元素。属性只能是一个指向单个DOM节点的元素的属性。返回一个由扩展元素组成的数组。

这个方法提供了相当方便的取元素的方法，供ancestors()，descentants()，nextSiblings()，previousSiblings()和siblings()内部使用，所以直接访问recursivelyCollect()的机会是比较少的。当然，如果你有什么特别的要求，它是你的一个选择。

示例

<ul id="fruits">
<li id="apples">
<ul id="list-of-apples">
<li id="golden-delicious"><p>Golden
Delicious</p></li>
<li id="mutsu">Mutsu</li>
<li id="mcintosh">McIntosh</li>
<li id="ida-red">Ida Red</li>
</ul>
</li>
</ul>

$('fruits').recursivelyCollect('firstChild');
// -> [li#apples, ul#list-of-apples, li#golden-delicious, p]

参看

Element： ancestors | descendants | nextSiblings | previousSiblings | siblings


remove::Element

remove(element) -> HTMLElement从document里完全删除element并返回它。

如果只是想暂时的隐藏起来，将来还要再用的，你应该用hide()方法。

示例

//之前：

<ul>
<li id="golden-delicious">Golden Delicious</li>
<li id="mutsu">Mutsu</li>
<li id="mcintosh">McIntosh</li>
<li id="ida-red">Ida Red</li>
</ul>

$('mutsu').remove();
// -> HTMLElement (and removes li#mutsu)

//之后

<ul>
<li id="golden-delicious">Golden Delicious</li>
<li id="mcintosh">McIntosh</li>
<li id="ida-red">Ida Red</li>
</ul>


removeClassName::Element

removeClassName(element, className) -> HTMLElement删除元素的CSS类名并返回它。

示例

<div id="mutsu" class="apple fruit food"></div>

$('mutsu').removeClassName('food');
// -> HTMLElement

$('mutsu').classNames();
// -> ['apple', 'fruit']


replace::Element

replace(element[, html]) -> HTMLElement用html的内容来替换element，返回被删除的element。

html可以是纯文本、HTML片段和任何含有toString方法的javascript对象。

任何包含的<script>标签都将在element被替换后被执行(replace内部会调用String.evalScripts)。

如果没有参数提供，那么replace只是清除element的内容。当然，用remove会比它更加快速也更加标准。

示例

<div id="food">
<div id="fruits">
<p id="first">Kiwi, banana <em>and</em> apple.</p>
</div>
</div>

传入一个HTML片段：

$('first').replace('<ul id="favorite"><li>kiwi</li><li>banana</li><li>apple</li></ul>');
// -> HTMLElement (p#first)
$('fruits').innerHTML;
// -> '<ul id="favorite"><li>kiwi</li><li>banana</li><li>apple</li></ul>'

含有<script>的HTML片段：

$('favorite').replace('<p id="still-first">Melon, oranges <em>and</em>
grapes.</p><script>alert("removed!")</script>');
// -> HTMLElement (ul#favorite) and prints "removed!" in an alert dialog.
$('fruits').innerHTML
// -> '<p id="still-first">Melon, oranges <em>and</em> grapes.</p>'

纯文本：

$('still-first').replace('Melon, oranges and grapes.');
// -> HTMLElement (p#still-first)
$('fruits').innerHTML
// -> 'Melon, oranges and grapes.'

最后，靠toString()方法：

$('fruits').update(123);
// -> HTMLElement

$('food').innerHTML;
// -> '123'


scrollTo::Element

scrollTo(element) -> HTMLElement卷动窗口让元素显示在视口的顶部，返回这个元素。

这与使用HTML的锚(a)是类似的效果（只是没有引起浏览器的历史记录的变化）。

示例

$(element).scrollTo();


setStyle::Element

setStyle(element, styles) -> HTMLElement修改元素的CSS风格属性。styles是按属性-值对这样的哈希形式传入的，并且属性是按驼峰式指定的。

示例

$(element).setStyle({
backgroundColor: '#900',
fontSize: '12px'
});
// -> HTMLElement

注意

这个方法透明的处理浏览器对float和opacity处理的不统一。由于float是关键字，所以要对它进行转义或者使用cssFloat。opacity接受0(完全透明)~1(完全不透明)之间的数值。下面的代码可以在各种浏览器中安全的使用：

$(element).setStyle({
cssFloat: 'left',
opacity: 0.5
});
// -> HTMLElement

$(element).setStyle({
'float': 'left', // notice how float is surrounded by single quotes
opacity: 0.5
});
// -> HTMLElement

并不是所有的CSS属性都支持。你可能只能使用DOM级别2的风格规范里描述的CSS属性。


show::Element

show(element) -> HTMLElement显然并返回元素。

示例

<div id="error-message" style="display:none;"></div>

$('error-message').show();
// -> HTMLElement (and displays div#error-message)

注意

show()不能显示由CSS隐藏的元素。这个不是Prototype的限制。而是由CSS的属性的显示过程来决定的。

<style>
#hidden-by-css {
display: none;
}
</style>

[…]

<div id="hidden-by-css"></div>

$('hidden-by-css').show(); // DOES NOT WORK!
// -> HTMLElement (div#error-message is still hidden!)

向后兼容变更

在Prototype以前的版本里，Element.toggle, Element.show, and Element.hide都可以传入任意多的元素。为了统一起见，1.5版的Prototype里已经不允许了。

但是你还是可以通过Enumerable来实现类似的结果：

['content', 'navigation', 'footer'].each(Element.show);

// -> ['content', 'navigation', 'footer']
// and displays #content, #navigation and #footer.

或者，更好的：

$('content', 'navigation', 'footer').invoke('show');

// -> [HTMLElement, HTMLElement, HTMLElement] (#content, #navigation and #footer)
// and displays #content, #navigation and #footer.

参看

Enumerable: invoke | each


siblings::Element

siblings(element) -> [HTMLElement...]收集所有的兄弟元素，以扩展元素的数组返回。

兄弟是指具有相同的父亲的元素。所以象head与body元素就是兄弟，他们的父亲是html元素。

返回的数组反映兄弟元素在文档中的顺序(比较索引为0表示靠近element的下一个兄弟)。

注意的是Prototype的DOM遍历忽略文本节点并且只返回元素节点。

示例

<ul>
<li id="golden-delicious">Golden Delicious</li>
<li id="mutsu">Mutsu</li>
<li id="mcintosh">McIntosh</li>
<li id="ida-red">Ida Red</li>
</ul>

$('mutsu').siblings();
// -> [li#golden-delicious, li#mcintosh, li#ida-red]


Element.Methods.Simulated

在一些非标准的浏览器中HTMLElement方法可能会不存在，因为你可以在extend元素的时候调用。Element.Methods.Simulated的作用是让你可以调用丢失的方法，让你觉得好象这个浏览器开发商突然决定去实现它们一样。

模块索引
hasAttribute
hasAttribute(element, attribute) -> Boolean

在没有的浏览器(IE6/7)里模拟标准DOM方法hasAttribute


stopObserving::Element

stopObserving(element, eventName, handler) -> HTMLElement注销处理函数，并且返回元素。

Event.stopObserving的一个简单的代理。更多的信息参考Event.stopObserving。

示例

$(element).stopObserving('click', coolAction);
// -> HTMLElement (and unregisters the 'coolAction' event handler).


toggle::Element

toggle(element) -> HTMLElement切换元素的可视性。

兄弟是指具有相同的父亲的元素。所以象head与body元素就是兄弟，他们的父亲是html元素。

返回的数组反映兄弟元素在文档中的顺序(比较索引为0表示靠近element的下一个兄弟)。

注意的是Prototype的DOM遍历忽略文本节点并且只返回元素节点。

注意

toggle()不能显示由CSS隐藏的元素。这个不是Prototype的限制。而是由CSS的属性的显示过程来决定的。

<style>
#hidden-by-css {
display: none;
}
</style>

[…]

<div id="hidden-by-css"></div>

$('hidden-by-css').toggle(); // DOES NOT WORK!
// -> HTMLElement (div#error-message is still hidden!)

向后兼容变更

在Prototype以前的版本里，Element.toggle, Element.show, and Element.hide都可以传入任意多的元素。为了统一起见，1.5版的Prototype里已经不允许了。

但是你还是可以通过Enumerable来实现类似的结果：

['error-message', 'welcome-message'].each(Element.toggle);
// -> ['error-message', 'welcome-message']
// and toggles the visibility of div#error-message and div#confirmation-message.

或者，更好的：

$('error-message', 'welcome-message').invoke('toggle');
// -> [HTMLElement, HTMLElement] (div#error-message and div#welcome-message)
// and toggles

参看

Enumerable: invoke | each


toggleClassName::Element

toggleClassName(element, className) -> HTMLElement切换元素的CSS类名并返回。

示例

<div id="mutsu" class="apple"></div>

$('mutsu').hasClassName('fruit');
// -> false

$('mutsu').toggleClassName('fruit');
// -> element

$('mutsu').hasClassName('fruit');
// -> true

参看

Element: hasClassName


undoClipping::Element

undoClipping(element) -> HTMLElement将元素makeClipping()之前的overflow的值恢复。并返回它。

示例

<div id="framer">
<img src="/assets/2007/1/14/chairs.jpg" alt="example" />
</div>

$('framer').undoClipping();
// -> HTMLElement (and sets the CSS overflow property to its original value).


undoPositioned::Element

undoPositioned(element) -> HTMLElement把元素原来放回makePositioned()之前的位置，并返回它。

函数把元素的绝对定位的孩子节点变成相对定义对最近的已经定位的祖先节点上。

示例

<p>lorem […]</p>
<div id="container">
<div id="element" style="position: absolute; top: 20px; left: 20px;"></div>
</div>

$('container').undoPositioned();
// -> HTMLElement

返回原来的状态，使用undoPositioned。

参看

Element: makePositioned


up::Element

up([cssRule][, index = 0]) -> HTMLElement | undefined 返回元素匹配cssRule的第一个祖先(或者index指定的祖先)。如果cssRule没有给出，所有的祖先都会被考虑。如果没有祖先匹配要求，那么返回undefined。

up()方法是终极的DOM遍历工具的一部分(查看up()、next()、previous()体会Prototype的风格的优美)。它允许准确的基于索引或基于CSS规则的对任何元素祖先的选择。

由于它忽略文本节点(它只返回元素)，所以你不用担心空白节点。

作为一个额外的奖励，所有的返回元素已经被扩展了。所以我们可以对它进行链式的使用：

$(element).down(1).next('li', 2).hide();

遍历DOM从来没有这么容易过！

参数

如果没有传入参数，方法就会返回第一个祖先(与调用parentNode类似，但是up()返回一个已经扩展的元素。

如果index传入，元素的相应的祖先就会被返回。(这与从ancestors()返回的元素数组里选择一个元素是一样的。注意第一个元素的索引是0。

如果cssRule定义了，那么up()将返回匹配的第一个祖先。

如果cssRule与index都指定，那么up()首先收集所有与指定的CSS规则匹配的祖先，然后返回与指定的index对应的祖先。

上述所有情况中，如果没有找到对应的祖先，那么会返回undefined。

示例

<html>
[…]
<body>
<ul id="fruits">
<li id="apples" class="keeps-the-doctor-away">
<ul>
<li id="golden-delicious">Golden Delicious</li>
<li id="mutsu" class="yummy">Mutsu</li>
<li id="mcintosh" class="yummy">McIntosh</li>
<li id="ida-red">Ida Red</li>
</ul>
</li>
</ul>
</body>
</html>

$('fruits').up();
// equivalent:
$('fruits').up(0);
// -> body

$('mutsu').up(2);
// -> ul#fruits

$('mutsu').up('li');
// -> li#apples

$('mutsu').up('.keeps-the-doctor-away');
// -> li#apples

$('mutsu').up('ul', 1);
// -> li#fruits

$('mutsu').up('div');
// -> undefined

参看

Element：down | previous | next


update::Element

update(element[, newContent]) -> HTMLElement 将元素的内容替换成newContent并返回元素。

html可以是纯文本、HTML片段和任何含有toString方法的javascript对象。

任何包含的<script>标签都将在element被替换后被执行(replace内部会调用String.evalScripts)。

如果没有参数提供，那么replace只是清除element的内容。

要注意的是这个方法在IE6或者更高的版本下允许无缝的对表内容进行更新。

示例

<div id="fruits">carrot, eggplant and cucumber</div>

分析一个正则字串：

$('fruits').update('kiwi, banana and apple');
// -> HTMLElement
$('fruits').innerHTML
// -> 'kiwi, banana and apple'

清空元素内容：

$('fruits').update();
// -> HTMLElement
$('fruits').innerHTML;
// -> '' (an empty string)

一个HTML片段：

$('fruits').update('<p>Kiwi, banana <em>and</em> apple.</p>');
// -> HTMLElement
$('fruits').innerHTML;
// -> '<p>Kiwi, banana <em>and</em> apple.</p>'

放进一个脚本：

$('fruits').update('<p>Kiwi, banana <em>and</em>
apple.</p><script>alert("updated!")</script>');
// -> HTMLElement (and prints "updated!" in an alert dialog).
$('fruits').innerHTML;
// -> '<p>Kiwi, banana <em>and</em> apple.</p>'

靠toString()方法：

$('fruits').update(123);
// -> HTMLElement
$('fruits').innerHTML;
// -> '123'

最后，你可以定义你自己的toString()，做一起有意思的事情。

var Fruit = Class.create();
Fruit.prototype = {
initialize: function(fruit){
this.fruit = fruit;
},
toString: function(){
return 'I am a fruit and my name is "' + this.fruit + '".';
}
}
var apple = new Fruit('apple');

$('fruits').update(apple);
$('fruits').innerHTML;
// -> 'I am a fruit and my name is "apple".'


visible::Element

visible(element) -> Boolean 返回一个布尔值表示元素是否可见(例如：是不是行内风格的属性被设置成"display:none")。

示例

<div id="visible"></div>
<div id="hidden" style="display: none;"></div>

$('visible').visible();
// -> true

$('hidden').visible();
// -> false

注意

通过CSS样式表设定的CSS样式并不在考虑之列你对这类元素的执行后，可能得到你不想要的结果。这个不是Prototype的限制。而是由CSS的属性的显示过程来决定的。

<style>
#hidden-by-css {
display: none;
}
</style>

[…]

<div id="hidden-by-css"></div>

$('hidden-by-css').visible();
// -> true


all::Enumerable

all([iterator = Prototype.K]) -> Boolean 确定所有的元素是等价的布尔真值，而不管通过计算的还是直接的。

这个代码很明显会在找到失败的元素后立即返回(即布尔值为false).如果没有迭代子提供,元素将会被直接使用.否则每个元素将会被传递给迭代子,以迭代结果作为计算的值.

示例

[].all()
// -> true (empty arrays have no elements that could be false-equivalent)

$R(1, 5).all()
// -> true (all values in [1..5] are true-equivalent)

[0, 1, 2].all()
// -> false (with only one loop cycle: 0 is false-equivalent)

[9, 10, 15].all(function(n) { return  n >= 10; })
// -> false (the iterator will return  false on 9)

$H({ name: 'John', age: 29, oops: false }).all(function(pair) { return
pair.value; })
// -> false (the oops/false pair yields a value of false)

参看

如果你想确定是不是至少有一个元素匹配一个规则,你最好用any

Enumerable: any


any::Enumerable

any([iterator = Prototype.K]) -> Boolean 确定至少一个元素是等价的布尔真值，而不管通过计算的还是直接的。

这个代码很明显会在找到成功的元素后立即返回(即布尔值为true).如果没有迭代子提供,元素将会被直接使用.否则每个元素将会被传递给迭代子,以迭代结果作为计算的值。

示例

[].any()
// -> false (empty arrays have no elements that could be true-equivalent)

$R(0, 2).any()
// -> true (on the second loop cycle, 1 is true-equivalent)

[2, 4, 6, 8, 10].any(function(n) { return  0 == n % 3; })
// -> true (the iterator will return  true on 6: the array does have 1+ multiple
of 3)

$H({ opt1: null, opt2: false, opt3: '', opt4: 'pfew!' }).any(function(pair) {
return  pair.value; })
// -> true (thanks to the opt4/'pfew!' pair, whose value is true-equivalent)

参看

如果你想确定是不是所有元素都匹配某一个规则,你最好用all

Enumerable: all


collect::Enumerable

collect(iterator) -> Array返回应用迭代子到每个元素后的结果。别名是map。

这个方法对于序列来说相当于是瑞士军刀。你可以将原始值转化成差不多所有可能的东西。

示例

['Hitch', "Hiker's", 'Guide', 'To', 'The',
'Galaxy'].collect(function(s) {
return s.charAt(0).toUpperCase();
}).join('')
// -> 'HHGTTG'

$R(1,5).collect(function(n) {
return n * n;
})
// -> [1, 4, 9, 16, 25]

优化的版本

这里有两个非常普遍的情况可以通过其它特殊方法更好的完成：
1、方法调用的情景：如果你想在所有的元素上调用相同的方法，可能还有一些参数，并且还要使用结果值。这可以很容易的由invoke来完成。
2、属性获取的情景：如果你想在所有的元素上取得相同的属性，并且使用它们。那对于pluck来说是举手之劳。
两个变体都比collect有更好的性能，因为它们避免了语法闭包的开消。

参看

Enumerable: pluck | invoke


Enumerable

Enmerable提供了大量有用的方法集用于枚举，也是说，对象可以象集合一样被处理。它可以说是Prototype的基石。

我们称Enumerable是一个模块，因为它是一个相关的方法有集合，不是为了独立的使用的，而是为了混合(即嵌入到与它相容的其它的对象中)使用的。"module"术语的意义来自于Ruby世界，并且非常适合。因为Enumerable至少部分地试图去模仿Ruby世界里的同名者。

在Prototype里，相当多的对象已经混合进了Enumerable了。最明显的例子是Array和Hash；但是你也会发现不明显一部分，比如ObjectRange和各类DOM或者AJAX相关的对象。

内容导航
  • 别名：都是关于以你的方式拥有的事情
  • 高效的使用它
  • 将Enumerable混入你的对象
  • 模块索引
别名：都是关于以你的方式拥有的事情

与Ruby上对应的类似，Enumerable为了让你更加舒适，为不少动作提供了不止一个名字。目的是当你的技术背景让你对其中的某一个比较熟悉时，以减少你的学习曲线。当然，文档会试图清楚的指明某一个名字是推荐的(基于可读性、广泛接受的直观性等等)。
这里是一些你将看到的别名：

  • map等于collect
  • find是推荐的，等价与detect
  • findAll与select等价
  • include与member等价
  • entries与toArray等价
高效的使用它

在使用Enumerable时，初学者常常只是因为对于API的不熟悉写出一些低级的以性能为代价的代码。这里有一些用例表示某一个方法会明显的比其它的方法快(通常还让代码的可读性更好)。下面是两种案例。

collect, invoke, pluck 和 each: 考虑这个用例

初学者往往倾向在任何时候操作所有的元素时用each，任何时候每个元素以同样的方式产生一个值是用collect。通常这样做是对的，但是特定的用例情况下，它可以写的更加的简洁、优雅，以及更佳的性能。

  • 当你对所有的元素调用相同的方法时，用invoke
  • 当你对所有的元素使用相同的属性时，用pluck

reject和findAll vs. partition

findAll/select方法返回所有匹配给定动作(注意是动作，即函数)的元素；reject方法返回所有不匹配给定动作的元素。特殊的，如果你两个集合都想要，你可以使用partition避免循环两次。

将Enumerable混入你的对象

现在，让我们假设你已经创建了你自己的类似集合的对象（比如：某种类型的集合、或者是某些从服务器取到的服务器端的数据范围，延迟装入的风格的）。你想让Enumerable能够混合进去（我们也推荐你这样做）。那你应该如何做呢？

Enumerable模块基本上对你的对象只有一个要求：提供一个方法名叫做_each(注意前面的下划线），接受一个函数作为唯一的参数，并包含一个“原生的迭代”算法，调用参数顺序的对每个元素进行执行。

如果each.Enumerable文档上详细描述的一样，它提供了所有的额外的层次上的处理（迭代的短路，数字的索引等等）。你只需要实现真正的基本的循环来满足你的内部结构。

如果这让你还是有点迷惑，可以看一看Prototype的Array、Hash或者ObjectRange的源代码。它们都是以它们自己的_each方法开始的，可以为你理解提供方便。

一旦你明白了这些，剩下的就是混合Enumerable了，当然这通常是在你定义你的方法前完成。只有这样，任何你对Enumerable方法的修改才会有效。那么，你的代码可能会与下面的代码类似。

var YourObject = Class.create();
Object.extend(YourObject.prototype, Enumerable);
Object.extend(YourObject.prototype, {
initialize: function() { // with whatever constructor
arguments you need
// Your construction code
},
_each: function(iterator) {
// Your iteration code, invoking iterator at every turn
},
// Your other methods here, including Enumerable overrides
});

显然，你的对象可以这样用：

var obj = new YourObject();
// Whatever use here, e.g. to fill it up
obj.pluck('somePropName');
obj.invoke('someMethodName');
obj.size();
// etc.

模块索引
all
all([iterator = Prototype.K]) -> Boolean

确定所有的元素是等价的布尔真值，而不管通过计算的还是直接的。

any

any([iterator = Prototype.K]) -> Boolean

确定至少一个元素是等价的布尔真值，而不管通过计算的还是直接的。

collect
collect(iterator) -> Array

返回应用迭代子到每个元素后的结果。别名是map

detect
detect(iterator) -> firstElement | undefined

找到第一个返回真的元素。别名是find方法，find认为是更容易读的名字。

each
each(iterator) -> Enumerable

Enumerable的基石。它让你能以原生的方式迭代所有的元素，然后返回Enumerable，从而允许链试的调用。

entries
entries() -> Array

更通用的toArray方法的别名。

find
find(iterator) -> firstElement | undefined

找到第一个返回真的元素。dedect的方便的别名，推荐的（更好读的）语法表达。

findAll
findAll(iterator) -> Array

返回符合条件的元素。select的别名。

grep
grep(regex[, iterator = Prototype.K]) -> Array

返回所有的字符表示与正则表达式匹配的元素。如果迭代子指定，那么它会被用来为每个选择的元素产生这个字符表示。

include
include(object) -> Boolean

确定对象是否在Enumerable里，基于==比较运算符。member的别名。

inject
inject(accumulator, iterator) -> accumulatedValue

基于迭代子所产生的前一个结果递增地构建一个结果值。可以用来构建数组、数字数额／平均值等等。

invoke
invoke(methodName[, arg...]) -> Array

对通常的使用each或者collect的优化：调用相同的方法，相同的参数，面向所有的元素。返回调用方法的结果。

map
map(iterator) -> Array

返回满足要求的元素集合。collect的更加方便的别名。

max
max([iterator = Prototype.K]) -> maxValue

返回最大的元素（或者基于元素的计算）。如果集合为空，返回undefined。元素或者直接比较、或者先应用迭代子然后比较返回值。

member
member(object) -> Boolean

确定对象是否在Enumerable里，基于==比较运算符。include的别名。

min
min([iterator = Prototype.K]) -> minValue

返回最小的元素（或者基于元素的计算）。如果集合为空，返回undefined。元素或者直接比较、或者先应用迭代子然后比较返回值。

partition
partition([iterator = Prototype.K]) -> [TrueArray, FalseArray]

将元素分成两组：一组是真，一组是假。通常根据javascript布尔计算方法，如果迭代子不为空，那就需要计算元素所代表的值。

pluck
pluck(propertyName) -> Array

对collect的优化：取得相同的属性。返回属性的值。

reject
reject(iterator) -> Array

返回迭代子为假的元素。

select
select(iterator) -> Array

findAll方法的别名。

size
size() -> Number

枚举型的大小。

sortBy
sortBy(iterator) -> Array

通过迭代子提供一个符合一定规范的自定义的排序的方法。

toArray
toArray() -> Array

返回一个枚举的数组。entries的别名。

zip
zip(Sequence...[, iterator = Prototype.K]) -> Array

把两个以上的顺列拉到一起（想象裤子上的拉链），给定一个元组的数组。每个元组中的一个原始的序列包含一个值。元组也可以被迭代子转成其它的东西。


detect::Enumerable

detect(iterator) -> firstElement | undefined找到第一个返回真的元素。别名是find方法，find认为是更容易读的名字。

参看

Enumerable: find


each::Enumerable

each(iterator) -> EnumerableEnumerable的基石。它让你能以原生的方式迭代所有的元素，然后返回Enumerable，从而允许链试的调用。

基于each的迭代是Enumerable的核心。转入的迭代子将会与两个参数一起被调用：
1、当前的迭代元素。
2、当前循环的数值索引，从0开始。第二个参数大部分时间是没有使用的(因此也没有声明)，但是有时使用起来是非常方便的。

$break和$continue

通常的javascript代码可以使用break与continue语句来实现循环的跳出。但是当使用迭代子时，你的代码是在循环的范围之外的：循环代码是在场景的后面。
为了给你提供相同的功能(既使没有那么优化)，Prototype提供了两个全局的异常对象:$break和$continue。抛出这些与循环中使用原生的语句是一样的。这些异常会在each内部很好的被捕获。

示例

['one', 'two', 'three'].each(function(s) {
alert(s);
});

[ 'hello', 'world'].each(function(s, index) {
alert(index + ': ' + s);
});
// alerts -> '0: hello' then '1: world'

// This could be done better with an accumulator using inject, but humor me
// here...
var result = [];
$R(1,10).each(function(n) {
  if (0 == n % 2)
    throw $continue;
  if (n > 6)
    throw $break;
result.push(n);
});
// result -> [1, 3, 5]

each vs. _each

如果你读了Enumerable的主页面，你可能会回忆起来；为了让类能够混合进Enumerable，它必须提供基本的循环代码与它的内部结构相匹配。这个基本的迭代方法必须叫做_each，并且它只接受一个参数：迭代子函数。你可以在主页面上找到进一步的详细信息。
基本上，Enumerable.each将由_each提供的实际循环代码上包装了：
1、对$break/$continue的支持，如果上面所描述的。
2、对值/索引的正确维护与传递。

版本优化

这里有一个非常普遍的情况可以通过其它特殊方法更好的完成：方法调用的情形。如果你想在所有的元素上调用相同的方法，可能还有一些参数，并且还要使用结果值。这可以很容易的由invoke来完成。

变体通常比each有更好的性能，因为它们避免了语法闭包的开消。但是它不累积结果值到数组，这可能不是你想要的。在任何情况下，你都可能在你的实际的案例中测试两个选项的性能指标。

参看

Enumerable: invoke


entries::Enumerable

entries() -> Array更通用的toArray方法的别名。

参看

Enumerable: toArray


find::Enumerable

find(iterator) -> firstElement | undefined找到第一个返回真的元素。dedect的方便的别名，推荐的（更好读的）语法表达。

这是全面搜索findAll的一个快捷版。它只返回第一个匹配的元素，如果没有匹配的元素，那么返回undefined。

示例

// An optimal exact prime detection method, slightly compacted.
function isPrime(n) {
if (2 > n) return false;
if (0 == n % 2) return (2 ==
n);
for (var index = 3; n / index > index; index +=
2)
if (0 == n % index) return false;
return true;
} // isPrime

$R(10,15).find(isPrime)
// -> 11

[ 'hello', 'world', 'this', 'is', 'nice'].find(function(s) {
return s.length <= 3;
})
// -> 'is'


findAll::Enumerable

findAll(iterator) -> Array返回符合条件的元素。select的别名。

这是一种grep的多功能版本。findAll让你定义你的筛选元素的规则，提供了最大的选择余地。

示例

$R(1, 10).findAll(function(n) { return 0 == n % 2; })
// -> [2, 4, 6, 8, 10]

[ 'hello', 'world', 'this', 'is', 'nice'].findAll(function(s) {
return s.length >= 5;
})
// -> ['hello', 'world']

参见

reject方法是它的对立方法。如果你需要根据某种规则把元素分成两组，参看partition。

Enumerable: reject | partition


grep::Enumerable

grep(regex[, iterator = Prototype.K]) -> Array返回所有的字符表示与正则表达式匹配的元素。如果迭代子指定，那么它会被用来为每个选择的元素产生这个字符表示。

这是findAll的一个变种，它是特定用于元素的模式匹配字符串表示的。它对于字符串序列非常有用；当然，对于任何含有toString方法、适合这种用法的对象都是非常有用的。

示例

// Get all strings with a repeated letter somewhere
['hello', 'world', 'this', 'is', 'cool'].grep(/(.)\1/)
// -> ['hello', 'cool']

$('myTable').descendants().grep(/t[dh]/, function(node) {
return node.tagName.toLowerCase();
})
// -> only td/th elements inside the table

// Get all numbers ending with 0 or 5
$R(1,30).grep(/[05]$/)
// -> [5, 10, 15, 20, 25, 30]


include::Enumerable

include(object) -> Boolean确定对象是否在Enumerable里，基于==比较运算符。member的别名。

注意，这里不是严格的等于(===，同时比较值与类型)，而是等价(只比较值，通过隐式转化)。

如果你需要检查元素是不是匹配某个给定的规则，你应该选择any。

示例

$R(1,15).include(10)
// -> true

['hello', 'world'].include('HELLO')
// -> false

[1, 2, '3', '4', '5'].include(3)
// -> true (== ignores actual type)


inject::Enumerable

inject(accumulator, iterator) -> accumulatedValue基于迭代子所产生的前一个结果递增地构建一个结果值。可以用来构建数组、数字数额／平均值等等。

注意，这里不是严格的等于(===，同时比较值与类型)，而是等价(只比较值，通过隐式转化)。

如果你需要检查元素是不是匹配某个给定的规则，你应该选择any。

示例

$R(1,10).inject(0, function(acc, n) { return acc + n; })
// -> 55 (sum of 1 to 10)

$R(2,5).inject(1, function(acc, n) { return acc * n; })
// -> 120 (factorial 5)

['hello', 'world', 'this', 'is', 'nice'].inject([], function(array, value,
index) {
if (0 == index % 2)
array.push(value);
return array;
})
// -> ['hello', 'this', 'nice']

注意我们怎样使用引用：

var array1 = [];
var array2 = [1, 2, 3].inject(array1, function(array, value) {
array.push(value * value);
return array;
});
array2
// -> [1, 4, 9]
array1
// -> [1, 4, 9]
array2.push(16);
array1
// -> [1, 4, 9, 16]

性能提示

当对数据进行插入时,你可以通过javascript的基于引用的方案来免费创建更大的复制过去的数组(与javascript的原生的concat方法相反,它会返回一个新的数组,这是确定的).


invoke::Enumerable

invoke(methodName[, arg...]) -> Array对通常的使用each或者collect的优化：调用相同的方法，相同的参数，面向所有的元素。返回调用方法的结果。

由它避免了对于匿名函数(就象你用each与collect一样)语法闭包的开销，这个性能上更好。或者更重要的是，它让代码更加简洁易懂。

示例

['hello', 'world', 'cool!'].invoke('toUpperCase')
// ['HELLO', 'WORLD', 'COOL!']

['hello', 'world', 'cool!'].invoke('substring', 0, 3)
// ['hel' 'wor', 'coo']

// Of course, this works on Prototype extensions (why shouldn't it?!)
$('navBar', 'adsBar', 'footer').invoke('hide')

参看

pluck方法用于取属性，功能相同。


map::Enumerable

map(iterator) -> Array返回满足要求的元素集合。collect的更加方便的别名。

参看

Enumerable: collect


max::Enumerable

max([iterator = Prototype.K]) -> maxValue返回最大的元素（或者基于元素的计算）。如果集合为空，返回undefined。元素或者直接比较、或者先应用迭代子然后比较返回值。

注意，对于相等的值，返回最后一个。

示例

$R(1,10).max()
// -> 10

['hello', 'world', 'gizmo'].max()
// -> 'world'

function Person(name, age) {
this.name = name;
this.age = age;
}

var john = new Person('John', 20);
var mark = new Person('Mark', 35);
var daisy = new Person('Daisy', 22);

[john, mark, daisy].max(function(person) {
return person.age;
})
// -> 35


member::Enumerable

member(object) -> Boolean确定对象是否在Enumerable里，基于==比较运算符。include的别名。

参看

Enumerable: include


min::Enumerable

min([iterator = Prototype.K]) -> minValue返回最小的元素（或者基于元素的计算）。如果集合为空，返回undefined。元素或者直接比较、或者先应用迭代子然后比较返回值。

注意，对于相等的值，返回最前面的那个。

示例

$R(1,10).max()
// -> 1

['hello', 'world', 'gizmo'].max()
// -> 'gizmo'

function Person(name, age) {
this.name = name;
this.age = age;
}

var john = new Person('John', 20);
var mark = new Person('Mark', 35);
var daisy = new Person('Daisy', 22);

[john, mark, daisy].max(function(person) {
return person.age;
})
// -> 20


partition::Enumerable

partition([iterator = Prototype.K]) -> [TrueArray, FalseArray]将元素分成两组：一组是真，一组是假。通常根据javascript布尔计算方法，如果迭代子不为空，那就需要计算元素所代表的值。

这是一个优于findAll/select和reject的解决办法：因为它只对所有元素循环一次。

示例

['hello', null, 42, false, true, ,
17].partition()
// -> [['hello', 42, true, 17], [null, false, undefined]]

$R(1, 10).partition(function(n) {
return 0 == n % 2;
})
// -> [[2, 4, 6, 8, 10], [1, 3, 5, 7, 9]]


reject::Enumerable

reject(iterator) -> Array返回迭代子为假的元素。

由它避免了对于匿名函数(就象你用each与collect一样)语法闭包的开销，这个性能上更好。或者更重要的是，它让代码更加简洁易懂。

示例

$R(1, 10).reject(function(n) { return 0 == n % 2; })
// -> [1, 3, 5, 7, 9]

[ 'hello', 'world', 'this', 'is', 'nice'].reject(function(s) {
return s.length >= 5;
})
// -> ['this', 'is', 'nice']

参看

findAll方法(以及别名select)与它相反。如果你需要将元素按某种规则分成两组，你可以看一下partition。

Enumerable: findAll | select | partition


select::Enumerable

select(iterator) -> ArrayfindAll方法的别名。

这是一个优于findAll/select和reject的解决办法：因为它只对所有元素循环一次。

参看

Enumerable: findAll


size::Enumerable

size() -> Number枚举型的大小。

这是一个优于findAll/select和reject的解决办法：因为它只对所有元素循环一次。

示例

$R(1, 10).size()
// -> 10

['hello', 42, true].size()
// -> 3

$H().size()
// -> 0

性能考虑

这个方法存在的唯一目的就是提供一个枚举对象通用的取大小的方法。默认的实现实际上是靠循环的，这也意味着它有线性的复杂度。大部分的对象与Enumerable混合后都会通过重定义size来进行优化。例如：Array，它重定义了size来托管数组原生的长度属性。

参看

Array: size


sortBy::Enumerable

sortBy(iterator) -> Array通过迭代子提供一个符合一定规范的自定义的排序的方法。

与比较标准相配的元素将保持原有的顺序。计算标准语义必须明确的定义出来(例如运算符<必须在任何两个标准中明确存在，即两个元素在不等时，大小是明确的)。

注意到数组已经有一个原生的sort方法，它依靠了数组元素的原生的顺序(比如两个元素之间运用<运算符比较后的语义)。你应该只在原生的顺序不存在或者不满足要求时使用sortBy。

示例

['hello', 'world', 'this', 'is', 'nice'].sortBy(function(s) {
returns.length; })
// -> 'is', 'this', 'nice', 'hello', 'world']

['hello', 'world', 'this', 'is', 'cool'].sortBy(function(s) {
var md = s.match(/[aeiouy]/g);
return null == md ? 0 : md.length;
})
// -> [ 'world', 'this', 'is', 'hello', 'cool'] (sorted by vowel count)


toArray::Enumerable

toArray() -> Array返回一个枚举的数组。entries的别名。

注意这让任何与Enumerable混合的对象都可以用于$A工具函数。

示例

$R(1, 5).toArray()
// -> [1, 2, 3, 4, 5]

性能考虑

显然，与Enumerable混合后的对象可以与Array一样改写默认的代码。

参看

Array: toArray


zip::Enumerable

zip(Sequence...[, iterator = Prototype.K]) -> Array把两个以上的顺列拉到一起（想象裤子上的拉链），给定一个元组的数组。每个元组中的一个原始的序列包含一个值。元组也可以被迭代子转成其它的东西。

对于以前没有接触过zip函数的人来说(例如与Haskell或者Ruby工作不多的)，这个函数的真实的行为可能会有点不要掌握。下面是一些可能有利于理解的例子。

示例

var firstNames = ['Justin', 'Mislav', 'Tobie', 'Christophe'];
var lastNames = ['Palmer', 'Maronhic', 'Langel', 'Porteneuve'];

firstNames.zip(lastNames)
// -> [['Justin', 'Palmer'], ['Mislav', 'Maronhic'], ['Tobie', 'Langel'],
['Christophe', 'Porteneuve']]

firstNames.zip(lastNames, function(a) { return a.join(' '); })
// -> ['Justin Palmer', 'Mislav Maronhic', 'Tobie Langel', 'Christophe
Porteneuve']

var cities = ['Memphis', 'Zagreb', 'Montreal', 'Paris'];
firstNames.zip(lastNames, cities, function(p) {
returnp[0] + ' ' + p[1] + ', ' + p[2];
})
// -> ['Justin Palmer, Memphis', 'Mislav Maronhic, Zagreb', 'Tobie Langel,
Montreal', 'Christophe Porteneuve, Paris']

firstNames.zip($R(1, 100), function(a) { return a.reverse().join('. '); })
// -> ['1. Justin', '2. Mislav', '3. Tobie', '4. Christophe']


Event

内容导航
  • ♫多么神奇的混乱♫
  • Prototype的拯救方法
  • 模块索引
♫多么神奇的混乱♫

事件处理对于跨平台来说是一个真正令人痛苦的点。
事实上，突出的问题是：每个人都按W3C的方式来做，而MSIE却完全按别一种方式来做。同时，还到处都是的一些微妙的、鬼鬼祟祟的的问题会咬你一口，比如基于KHTML的浏览器(Konqueror的Safari)上的keypress/keydown问题。当然MSIE在取消事件处理句柄时，还有一个容易内存泄漏的问题。

Prototype的拯救方法

当然，Prototype做的非常漂亮，所以你可能都忘记这些问题的存在了。进到Event的名字空间，你看到它被加入了很多方法(在这个页面从头到尾)，它们都将当前的事件对象当作参数，并且在所有主要的浏览器上高兴地产生你请求的信息。
Event也提供一个标准按键列表，你可以在按键相关的事件里使用。所有的这些键可能通过Event.KEY_xxx的方式来使用。下面是定义的一些常量：KEY_BACKSPACE, KEY_TAB, KEY_RETURN, KEY_ESC, KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_DOWN, KEY_DELETE, KEY_HOME, KEY_END, KEY_PAGEUP, KEY_PAGEDOWN。常量名字就它的意思。

你用的最多的函数的可能是observe, element和stop。对于其它的函数，你的使用情况不尽相同：这要看你的网页要做成什么样。

模块索引
element
Event.element(event) -> Element

返回事件发生的DOM元素。

findElement

Event.findElement(event, tagName) -> Element

返回给定tag名的第一个DOM元素，从指定的事件元素向上搜索。

isLeftClick
Event.isLeftClick(event) -> Boolean

确定按钮相关的鼠标事件是不是“左”按钮。

observe
Event.observe(element, eventName, handler[, useCapture = false])

在DOM元素上注册事件处理。

pointerX
Event.pointerX(event) -> Number

返回鼠标志事件的绝对的水平位置。

pointerY
Event.pointerY(event) -> Number

返回鼠标志事件的绝对的垂直位置。

stop
Event.stop(event)

停止事件的传播并且阻止默认动作被触发。

stopObserving
Event.stopObserving(element, eventName, handler[, useCapture = false])

注销一个事件处理。

unloadCache
Event.unloadCache()

注销所有通过observe注册的事件处理。自动为你关联。


element::Event

Event.element(event) -> Element返回事件发生的DOM元素。

应该注意如果浏览器不支持原生的DOM扩展(下面将进一步解释)，你得到的元素可能会不是很好的被扩展上。如果你确实想在它上面用Element.Methods，你需要通过$()函数包装起来调用。

示例

下面是一个简单的代码。它让你随意在页面上点击，如果你点中了段落，就会把它隐藏起来。

Event.observe(document.body, 'click', function(event)
{
var elt = Event.element(event);
if ('P' == elt.tagName)
$(elt).hide();
});

参看

这个函数与findElement有一个微妙的不同。

Event: findElement


findElement::Event

Event.findElement(event, tagName) -> Element返回给定tag名的第一个DOM元素，从指定的事件元素向上搜索。

有时，你可能不关心实际上你点的元素是什么。有时，你可能关心它的最近的元素(要么里点的那个，要么是它的容器，或者是它容器的容器，等等)，通过它的标签来确定(比如<p>)。这就是findElement的功能。
提供的标签比较时是不区分大小写的。

如果没有找到匹配的元素，文档本身(HTMLDocument节点)会返回。

示例

下面是一段简单的代码，让你可以随便的点击页面，然后隐藏点击周围最近的落段(如果有的话)。

Event.observe(document.body, 'click', function(event)
{
var elt = Event.findElement(event, 'P');
if ('P' == document)
$(elt).hide();
});

更复杂的搜索，你可能需要得到实际的那个元素，然后在上面进行up操作，它能让你用CSS语法来表达你的要求，同时也搜索更多的匹配项(同时，结果是确保扩展的)：

Event.observe(document.body, 'click', function(event)
{
// First element from event source with 'container' among its CSS classes
var elt = $(Event.element(event)).up('.container');
// Or: second DIV from the event source
// elt = $(Event.element(event)).up('div', 1);
// Or: second DIV with 'holder' among its CSS classes...
// elt = $(Event.element(event)).up('div.holder', 1);
elt.hide();
});

参看

如果你在找直接被事件击中的元素，你应该使用element函数

Event: element


isLeftClick::Event

Event.isLeftClick(event) -> Boolean确定按钮相关的鼠标事件是不是“左”按钮。

注意：这里并没有绝对的左，而是默认左(即通常的右手顺的)。在为左撇子设置的系统里，基本的按钮是右边的，这个函数会正确的检测出来的。


observe::Event

Event.observe(element, eventName, handler[, useCapture = false])在DOM元素上注册事件处理。

重要提示

首先，如果你以前有用过HTML的事件属性(如<body onload="return myFunction()">)或者DOM级别-0事件属性(如window.onload=myFunction;);你现在需要摆脱这些蹩足的方法:-)同时理解observe究竟做什么。
它不是取代已经存在的相同的元素与事件的处理函数，而是在上面增加处理函数。使用observe不能让原来的代码失效。

这些参数都是什么意义?
  1. 你想observe的DOM元素。与其它的Prototype函数一样，这个既可以是一个实际的DOM引用也可以是一个元素的ID的字符串。
  2. 标准的事件名，由浏览器支持的不同级别的DOM事件(通常是DOM级别2事件)。象click这样简单的事件。
  3. 处理函数。它可以是一个匿名函数、有名函数、一个绑定的事件侦听者。这全由你决定。
  4. 你也可以选择的捕获而不是起泡。详细情况在DOM规范里有说明。要注意的是捕获不少主流的浏览器没有支持，所以你很少会需要它。大部分时间，你没有必要提供这个参数。

这么多参数，提这个需求的人也经常会忘记...

为了把函数注册成处理函数，你想侦听的DOM元素必须存在于DOM之中(也就是说，在你调用你的注册过程时，它就已经在源码里或者动态的创建并插入了) .

一个简单的例子

想象下面这样的(X)HTML片段:

<form id="signinForm" method="post" action="/auth/signin">
…
</form>

这里是怎样注册你的函数checkForm到form的submit事件上.

Event.observe('signinForm', 'submit', checkForm);

当然,如果你想这段代码在form在DOM中出现进执行;但是将脚本代码嵌在文档中又是一件非常不好的事情.所以我们找到了一个非常简单的办法,等待到页面完全加载:

Event.observe(window, 'load', function() {
Event.observe('signinForm', 'submit', checkForm);
});

只是一点点的封装.

注意:如果你的页面很大,你可能想让这段代码在页面全部装完前执行:只要这个DOM装入就可以了.现在没有标准的事件来支持它.但这里有一个有用的文章你可以参考.

方法需要用到this的特殊情况

当把事件处理函数当成函数参数传递时,函数就会失去关联信息.也就是说,对于最初始的函数的意义不明确了.如果你传了一个需要使用this引用的方法(比如,访问他的容器对象的属性),那你就会有麻烦.

或者你不会.

因为这是prototype特别声明的问题,它提供了bindAsEventListener.查一下相关的资料,如果你还是不太熟悉的话.使用的方法很简单:

var Checks = {
// some stuff our 'generic' function needs

generic: function(event) {
// Some generic, all-purpose checking (e.g.
empty required fields)
}
};

Event.observe('signinForm', 'submit',
Checks.generic.bindAsEventListener(Checks));

参看

相关的函数stopObserving和unloadCache,值特你一看.


pointerX::Event

Event.pointerX(event) -> Number返回鼠标志事件的绝对的水平位置。

注意:位置是页面上的绝对位置.不是视口上的:在相同的视口位置向右卷会增加这个事件的返回值.


pointerY::Event

Event.pointerY(event) -> Number返回鼠标志事件的绝对的垂直位置。

注意:位置是页面上的绝对位置.不是视口上的:在相同的视口位置向下卷会增加这个事件的返回值.


stop::Event

Event.stop(event)停止事件的传播并且阻止默认动作被触发。

浏览器处理一个被触发的事件包含了两个方面:

  • 浏览器通常是触发事件发的那个元素的处理函数,然后是它的父亲元素,然后再这样接下去,直到文档的根元素.这叫做事件冒泡,也是最普遍的传播方式.你可能在处理了一个事件后想停止传播,不再想或者不再需要他再向上冒泡下去.
  • 一旦你的代码有机会被事件执行.那么浏览器的默认的行为也会被执行.比如,点击链接就会浏览它们,提交表单就会发送它们到服务器,打回车键在一个单行的表单域会提交它;等等.如果你要做自己的处理,你可能非常想阻止这些默认的行为.

因为停止其中的一个,在99%的情况下,也能阻止另外一个.prototype把它们两个都放到了stop里面.在一个事件对象里调用它来停止传播并且阻止默认的行为.

示例

Event.observe('signinForm', 'submit',
function(event) {
var login = $F('login').strip();
if ('' == login) {
Event.stop(event);
// Display the issue one way or another
}
});


stopObserving::Event

Event.stopObserving(element, eventName, handler[, useCapture = false])注销一个事件处理。

这个函数的参数的意义与observe是一样的.它注销一个事件处理函数,所以这个处理函数将不会再被这个元素(elelment)与这个事件(event)组合所调用.

为什么它不停止侦听?

为了让stopObserving工作,你必须传入与调用observe时相同的参数.尊从这一点看起来是非常直接的.但是这里有一个常见的情况,代码与我们所想要的不不一样. ：

var obj = {
…
fx: function(event) {
…
}
};

Event.observe(elt, 'click', obj.fx.bindAsEventListener(obj));
…

// THIS IS WRONG, DON'T DO IT!
Event.stopObserving(elt, 'click', obj.fx.bindAsEventListener(obj)); // Won't
work!

虽然第一眼看起来似乎没有问题,但是你必须记住的是bindAsEventListener返回的是一个全新的匿名函数,它包含着你的方法.这意味着每次你的调用都返回一个新的函数.因为这个请求停止的代码实际上调用的是另一个函数.而不是你侦听时所用的函数.所以不会有匹配的函数被发现,原来的侦听原封不动的保留着.

为了避免这种情况,你需要"缓存"这个边界函数(也是, script.aculo.us在很多的类里所做的一样).就象这样.

示例

var obj = {
…
fx: function(event) {
…
}
};

obj.bfx = obj.fx.bindAsEventListener(obj);

Event.observe(elt, 'click', obj.bfx);
…
Event.stopObserving(elt, 'click', obj.bfx);

参看

unloadCache函数是相关的,并且值得一看的.


unloadCache::Event

Event.unloadCache()注销所有通过observe注册的事件处理。自动为你关联。

关于MSIE, 事件处理, 内存泄漏的痛苦的故事

MSIE有一个非常重要的问题,有很多情况下,它不会取消对事件的侦听,当页面已经被卸载.这些处理函数还会在内存里保存,慢慢填满内存,阻碍游览器的要道.这就是内存泄漏.

当然,手工保留所有的事情标签是非常麻烦的.也就是说——土!

这也是Prototype为你所考虑好的。它保存了所有的标签，当unloadCache调用后，它会注销所有函数同时释放引用。这实际上一种类似于垃圾回收的机制。

你甚至不需要知道

更好的是，Prototype专门为MSIE自动安装了对页面的卸载使用的钩子。所以你不用做任何事。所有的事情都已经被处理了，我们只是认为你可能想知道。所以做点有创造性的事情，比如增值的javascript代码。我们不会在这里用可自动化的细节代码来阻碍你的理解。


Form

Form是一个名字空间,对于所有与form相关的事件的模块,它包装了form的操作和串行化的好处在里面.

它包含了form整体的处理方法,而它的子模块Form.Element则处理特定的form控件.大部分的方法也能直接从扩展过的form元素上得到.(参看"怎样扩展DOM")

模块索引
disable
disable(formElement) -> HTMLFormElement

禁止整个Form，Form上的控件可以看见，但是不能编辑。

enable

enable(formElement) -> HTMLFormElement

让全部或者部分被禁用的Form可用。

findFirstElement
findFirstElement(formElement) -> HTMLElement

找到第一个没有隐藏，没有被禁用的form控件。

focusFirstElement
focusFirstElement(formElement) -> HTMLFormElement

把按键的焦点定在第一个控件上。

getElements
getElements(formElement) -> array

返回form里的所有控件。

getInputs
getInputs(formElement [, type [, name]]) -> array

返回Form上所有的INPUT元素的数组。通过指定type与name参数，限制查找的范围。

reset
reset(formElement) -> HTMLFormElement

将表单复位到原来的值。

serialize
serialize(formElement) -> string

将表单的数据串行化成适合Ajax请求的字符串。

serializeElements
serializeElements(elements) -> string

将一个表单的元素数组进行串行化。


disable::Form

disable(formElement) -> HTMLFormElement 禁止整个Form，Form上的控件可以看见，但是不能编辑。

通过迭代Form上的元素然后禁用它们来实现对Form的禁用。

示例

<form id="disable-example" class="example" action="#">
<input type="text" name="username" id="username" value="Sulien">
<input type="text" name="age" id="age" value="23" size="3" >

<button type="submit">Send</button>
</form>

$('disable-example').disable();

注意

要记住，失效的元素在串行化时会被忽略！你也不能串行化一个失效的Form。


302 Found

Found

The document has moved here.


enable::Form

enable(formElement) -> HTMLFormElement让一个部分或者全部失效的Form生效。

通过迭代Form上的元素然后启用它们来实现对Form的启用。

示例

$(form).enable();

注意

这个方法会把Form上的所有的元素生效，不管他是不是被禁过（通过脚本或者通过HTML属性）。


findFirstElement::Form

findFirstElement(formElement) -> HTMLElement找到第一个没有隐藏，没有被禁用的form控件。

返回的对象是INPUT, SELECT或者TEXTAREA元素。这个方法被focusFirstElement()方法使用。

注意

这个方法返回的结果是文档中第一个元素的顺序，不是tab索引的顺序。


focusFirstElement::Form

focusFirstElement(formElement) -> HTMLFormElement把按键的焦点定在第一个控件上。

使用Form.findFirstElement()得到第一个元素，并调用它上面的activate()方法。这上样就会将焦点集中到表单页面的第一个元素上，这对于你的网站上的一个类似于搜索表单或者联系信息表单来讲，是一个易用性的提高。因为这个时间用户一般已经处于准备输入的状态了。


getElements::Form

getElements(formElement) -> array返回form里的所有控件。

注意：OPTION元素不包括在内。只有它的父元素SELECT会被放到结果里。


getInputs::Form

getInputs(formElement [, type [, name]]) -> array返回Form上所有的INPUT元素的数组。通过指定type与name参数，限制查找的范围。

示例

var form = $('myform')

form.getInputs() // -> all INPUT elements
form.getInputs('text') // -> only text inputs

var buttons = form.getInputs('radio', 'education')
// -> only radio buttons of name "education"

// now disable these radio buttons:
buttons.invoke('disable')

注意

INPUT元素按文档里的顺序返回，不是按Tab索引的顺序。


request::Form

enable(formElement) -> HTMLFormElement让一个部分或者全部失效的Form生效。

传给request()的选项(options)会自动与底层的Ajax.Request选择合并：

  • 如果Form有一个方法属性，它的值就会被用来作为Ajax.Request方法的选项。如果options指定，那么它有比Form的方法属性更高的优先级。如果两个属性都不存在，那么默认是"POST".
  • 在参数选项里指定的Key-value对（哈希或者查询字符串）会与序列化的Form参数合并起来。
示例：

假设你有下面的HTML表单:

<form id="person-example" method="POST" action="/user/info">
<fieldset>
<legend>User info</legend>
<div>
<label for="username">Username:</label>
<input type="text" name="username" id="username" value="" />
</div>
<div>
<label for="age">Age:</label>
<input type="text" name="age" id="age" value="" size="3" />
</div>
<div>
<label for="hobbies">Your hobbies are:</label>
<select name="hobbies[]" id="hobbies" multiple="multiple">
<option>coding</option>
<option>swimming</option>
<option>hiking</option>
<option>drawing</option>
</select>
</div>
<div class="buttonrow"><input type="submit" value="serialize!" /></div>
</fieldset>
</form>

$('person-example').request(); //done - it's posted

// do the same with a callback:
$('person-example').request({
onComplete: function(){ alert('Form data saved!') }
})

如果要修改HTTP方法并增加一些参数，只需要简单在option里使用方法与参数就可以了。下面的例子我们把方法设置成了GET，并增加了两个固定的参数：interests和hobbies。后面的参数已经在表单上设置了，但是在这里指定有更高的优先级。

$('person-example').request({
method: 'get',
parameters: { interests:'JavaScript', 'hobbies[]':['programming', 'music'] },
onComplete: function(){ alert('Form data saved!') }
})


reset::Form

reset(formElement) -> HTMLFormElement将表单复位到原来的值。

通过迭代Form上的元素然后启用它们来实现对Form的启用。

示例

Form.reset('contact')

// equivalent:
$('contact').reset()

// both have the same effect as pressing the reset button

这个方法允许你的程序reset一个form。他是对原生的HTMLFormElement的reset()方法的封装。


serialize::Form

serialize(formElement) -> string将表单的数据串行化成适合Ajax请求的字符串。

结果是类似于"name=johnny&color=blue"这样的字符串，适合于作为Ajax的请求。这个方法模拟了浏览器原始的串行化表单的方法，所以可以无刷新的发送表单数据。

示例

<form id="person-example" class="example" action="#">
<input type="text" name="username" id="username" value="Sulien" />
<input type="text" name="age" id="age" size="3" value="22" />

<select name="hobbies" id="hobbies">
<option value="coding">Coding</option>
<option value="swimming">Swimming</option> <!-- selected -->
<option value="hiking">Hiking</option>
<option value="drawing">Drawing</option>
</select>

<button type="submit">Send</button>
</form>

$('person-example').serialize()
// -> 'username=sulien&age=22&hobbies=swimming'

注意

被禁止的表单元素不被串行化(与w3c HTML建议统一)。
当然，文件也被忽略，因为它们不能被串行化，并且只用JavaScript发送。

如果我们发送给PHP或者是Ruby on Rails这样的后台，要记住"hobbies"这样的多选元素，一定要被命名成"hobbies[]"，因为我们是发送一个数组，不是发送一个元素。这与Javascript完全没有关系—Prototype也对h此不做任何处理，完全由你来决定。


serializeElements::Form

serializeElements(elements) -> string将一个表单的元素数组进行串行化。

推荐的串行化表单的方法是Form.serialize。但是serializeElements可以让你指定你想要的元素进行串行化，只取出form所有元素的子集。

示例

将所有的text类型的INPUT元素串行化：

Form.serializeElements( $('myform').getInputs('text') )
// -> serialized data


activate::Form.Element

activate(element) -> HTMLElement把焦点转移到表单控件上，如果它是一个文字INPUT，那么选中它的内容。

这个方法只是对元素取焦点同时选择的快捷方法；所以下面这些代码是等价的：

Form.Element.focus('myelement').select()
$('myelement').focus().select()
$('myelement').activate()

猜一下那个方法是优雅的:)


clear::Form.Element

clear(element) -> HTMLElement清空文字INPUT的内容。

示例

这段代码建立了一个这样的文字域：在它第一次得到焦点时清空它的内容。

$('some_field').onfocus = function()
{
// if already cleared, do nothing
if (this._cleared) return

// when this code is executed, "this" keyword will in fact be the field
itself
this.clear()
this._cleared = true
}


Form.Element

这是一个处理表单控件的方法集合。他们提供了从一个特定的控件上focus，serialize，disable/enable或者extract当前值的方法。

这是一个处理表单控件的方法集合。他们提供了从一个特定的控件上focus，serialize，disable/enable或者extract当前值的方法
在Prototype里，Form.Element也是一个值域的别名，所有的这些方法都可以在扩展(参看“怎样扩展DOM”)后的INPUT，SELECT和TEXTAREA里直接得到。因此下面这些是等价的：

· Form.Element.activate('myfield')

· Field.activate('myfield')

· $('myfield').activate()

很显然，你应该选择最短的形式放在相应的位置上。这些方法的大部分是返回元素自己的(在返回类型上指明)，这样方便了代码的连接处理。

模块索引
activate
activate(element) -> HTMLElement

把焦点转移到表单控件上，如果它是一个文字INPUT，那么选中它的内容。

clear

clear(element) -> HTMLElement

清空文字INPUT的内容。

disable
disable(element) -> HTMLElement

禁止一个表单控件，防止它的值在重新生效前被改动。

enable
enable(element) -> HTMLElement

让一个被禁用的控件生效。

focus
focus(element) -> HTMLElement

让键盘输入焦点切换到这个元素。

getValue
getValue(element) -> string | array

返回表单控件的当前值。大部分控件返回字符串；只有多先框返回数组。它的全局的快捷方法是$F()。

present
present(element) -> boolean

如果文字INPUT有内容，返回true，否则false。

select
select(element) -> HTMLElement

选择当前的文字INPUT里的内容。

serialize
serialize(element) -> string

创建一个URL-encoded的字符串，用name=value的形式来表示一个表单控件。


disable::Form.Element

disable(formElement) -> HTMLFormElement 禁止一个表单控件，防止它的值在重新生效前被改动。

这个方法把元素原生的disable属性设置成true。你可以通过这个属性来检查这个控件的状态。

示例

查看Form.disable()方法的例子，那个实际上就是这个。

注意

失效的表单控件永远不会被串行化！

不要在没有通过服务器端验证时通过禁止一个控件作为安全控制的方法。一个没有多少经验的Javascript用户也可以很容易的通过任何浏览器来使这些属性生效。相反，应该把禁止当成是一个可用性的增强—通过它你可以指示一个特定的值在当前时间是不是能被改变。


enable::Form.Element

enable(element) -> HTMLElement让一个被禁用的控件生效。

示例

查看Form.disable()方法的例子，那个实际上就是这个。


focus::Form.Element

focus(element) -> HTMLElement让键盘输入焦点切换到这个元素。

通过迭代Form上的元素然后禁用它们来实现对Form的禁用。

示例

Form.Element.focus('searchbox')

// equivalent:
$('searchbox').focus()


getValue::Form.Element

getValue(element) -> string | array返回表单控件的当前值。大部分控件返回字符串；只有多先框返回数组。它的全局的快捷方法是$F()。


present::Form.Element

present(element) -> boolean如果文字INPUT有内容，返回true，否则false。

通过迭代Form上的元素然后禁用它们来实现对Form的禁用。

示例

<form id="present-example" class="example" action="#">
<input type="text" name="username" id="username"/>
<input type="text" name="email" id="email" size="30"/>

<button type="submit">Send</button>
</form>
<div id="msg" class="notification"></div>

$('present-example').onsubmit = function(){
  var valid, msg = $('msg')

// are both fields present?
valid = $(this.username).present() && $(this.email).present()

  if (valid) {
// in real world we would return true here to allow the form to be submitted
// return true
msg.update('Passed validation').style.color = 'green'
} else {
msg.update('Please fill out all the fields.').style.color = 'red'
  }
  return false
}


select::Form.Element

select(element) -> HTMLElement选择当前的文字INPUT里的内容。

示例

当接收到焦点时，有一些搜索框将自动选择他们的内容：

$('searchbox').onfocus = function() {
Form.Element.select(this)
// however, much shorter is to just call:
this.select()
}


serialize::Form.Element

serialize(element) -> string创建一个URL-encoded的字符串，用name=value的形式来表示一个表单控件。

这个方法的结果是一个适合Ajax请求的字符串。但是它只串行化一个元素。如果你需要串行化所有的form元素，请使用Form.serialize()。

注意

串行化一个失效的控件或者一个没有名字的控件都会返回一个空的字符串。
如果你只是一个元素的值，而不是Ajax请求，那么你可以用getValue()。


bind::Function

bind(thisObj[, arg...]) -> Function提供一个保证与原始函数绑定等价的函数，还可以提供提前填入的参数。

与在Function主页上讨论的情况一样，绑定有时候会是一个非常难缠的问题。

但是Prototype保证你的函数会在你想要的对象上执行它的this，你所要做的就是调用一下bind函数(也非常欢迎你缓冲返回的函数，然后根据你的需要任意调用)。

示例

这是基本的用法。只保证了引用的正确调用。

var obj = {
name: 'A nice demo',
fx: function() {
alert(this.name);
}
};

window.name = 'I am such a beautiful window!';

function runFx(f) {
f();
}

var fx2 = obj.fx.bind(obj);

runFx(obj.fx);
runFx(fx2);

现在，还只是很少人知道的是，bind也能被用来提前准备参数给最后的参数表用。

var obj = {
name: 'A nice demo',
fx: function() {
alert(this.name + '\n' + $A(arguments).join(', '));
}
};

var fx2 = obj.fx.bind(obj, 1, 2, 3);
fx2(4, 5); // Alerts the proper name, then "1, 2, 3, 4, 5"


bindAsEventListener::Function

bindAsEventListener(thisObj[, arg...]) -> Function一个专门用于事件处理的bind函数的变体，它保证函数能将当前的事件对象以第一个参数的形式得到。

如果你不清楚“绑定”是什么，你要看一下Function的API页。如果你不明白bind做了什么，你要看一下bind的特定文章。
当你想创建一个事件处理的函数，不管怎样你需要得到当前的事情。W3C统一的办法是浏览器将它当成是第一个参数传递给你的函数。这是很好的。但是象IE这样的浏览器并不能支持，所以你不得不又象钻钢圈一样做高难度动作了。

为了把你这中解脱出来，Prototype让你绑定一个函数成事件的侦听者。这仍是一种绑定形式，所以你还是首先要指定this引用要保证的对象。但是这里Prototype保证它的第一个参数是当前的事件。任何你指定的参数都将跟在它后面加入到参数表中。

你通常把这个方法与Event.observe一起联起来用，包括任何你需要将一个函数作为一个事件侦听者时。

示例

这是基本的用法。只保证了引用的正确调用。

var obj = {
name: 'A nice demo',
fx: function(e) {
var tag = Event.element(e).tagName.toLowerCase();
var data = $A(arguments).shift();
alert(this.name + '\nClick on a ' + tag
+ '\nOther args: ' + data.join(', '));
}
};

Event.observe(document.body, 'click', obj.fx.bindAsEventListener(obj, 1, 2, 3));
// -> Any click on the page displays obj.name, the lower-cased tag name of the
// clicked element, and "1, 2, 3".


Function

内容导航
  • 什么是绑定？
  • 说的什么？
  • Prototype的补救办法？
  • 模块索引
什么是绑定

绑定实际上决定着函数运行时this关键字的含义。而由于通常的属性默认绑定(指任何时间对象的方法被调用)，this有时候可能会“丢失”。比如把函数引用当成是参数进行传递。

说的什么？

这里有一个例子：

var obj = {
name: 'A nice demo',

fx: function() {
alert(this.name);
}
};

function runFx(f) {
f();
}

window.name = 'I am such a beautiful window!';

obj.fx(); // This works fine, displaying "A nice demo."
runFx(obj.fx); // This goes awry, displaying "I am such a beautiful window!"

第二个调用失败的原因是：将obj.fx当成是一个平常的函数引用进行传递，丢失了它对obj的绑定。而是绑定到了然runFx的this上了，而这个this是window对象。

Prototype的拯救方法

Prototype解决了这个问题。你会发现在任何函数上多了两个新的方法：一个用于保证绑定(至于保证了早期的参数)，另一个则专门服务于作为事件处理的函数。参看以下列表：

模块索引
bind
bind(thisObj[, arg...]) -> Function

提供一个保证与原始函数绑定等价的函数，还可以提供提前填入的参数。

bindAsEventListener

bindAsEventListener(thisObj[, arg...]) -> Function

一个专门用于事件处理的bind函数的变体，它保证函数能将当前的事件对象以第一个参数的形式得到。


Hash

哈希可以被想象成是一个关系数组，绑定了唯一的键与值的对应(唯一不是必须的)，虽然它不能保证在迭代时元素的顺序的一致。由于是JavaScript程序设计语言本身的特性，所以所有的对象实际上都是哈希；但是Hash增加很多功能，让你可以枚举键和值，在键/值对上迭代，将两个哈希合并，将哈希编码成一个查询字符串表达式，等等。

内容导航
  • 创建哈希
  • 组合的示例
  • 注意事项!
  • 模块索引
创建哈希

这里有两种办法构建一个哈希实例:每一种是用常规的JavaScript对象初始化关键字new，第二种是使用$H函数。传一个普通的JavaScript对象会得到一个克隆，而不会改变原来的原始对象，但是传入一个Hash实例给$H()将会相同的例。

你也可以两个方法都不给参数，他们会默认一个空的哈希。

组合的示例

var h = $H({ name: 'Prototype', version:
    1.5 });
// equivalent:
var h = new Hash({ ... });

h.keys().sort().join(', ')
// -> 'name, version'

h.merge({ version: '1.5 final', author: 'Sam Stephenson'
    });
h.each(function(pair) {
alert(pair.key + ' = "' + pair.value + '"');
});
// Alerts, in non-guaranteed order, 'name = "Prototype"', 'version = "1.5 final"'
    and 'author = "Sam Stephenson"'.

$H({ action: 'ship', order_id: 123, fees: ['feel',
    'fee2'] }).toQueryString()
// -> action=ship&order_id=123&fees=fee1&fees=fee2

注意事项

Hash由于混入了Enumerable不能随便用任意的键，同时它的方法也是这样。增加一个与方法同名的键值就会导到原来的方法无法再被调用。你可以不用管那些你不用管的方法，但是你应该考虑一下下面的情况：

var h = new Hash({ ... });
h['each'] = 'my own stuff';
h.map();
// -> errors out because 'each' is not a function

在Enumerable里最重要方法是'each'，并且由于几乎所有的其它方法都使用了它，改写它将导致我们的Hash实例基本上没有用处。你也不能忽略'_each'，它也是Enumerable内部的方法.

模块索引
each
each(iterator) -> Hash

对哈希的键/值对进行迭代。

inspect

inspect() -> String

返回hash形式的面向调试的字符串表示。

keys

keys() -> [String...]

给出哈希的键(即属性名)数组。

merge

merge(hash) -> alteredHash

把传入的哈希的数据对注入到当前的哈希中，然后返回。

remove

remove(key) -> value
remove(key1, key2...) -> Array

从哈希里删除键值，并且发回这些键值。

toQueryString

toQueryString() -> String

把哈希转成是url-encoded形式的请求字符串的表示方式。

values

values() -> Array

把哈希的值以数组的形式返回。


each::Hash

each(iterator) -> Hash对哈希的键/值对进行迭代。

这实际上是混入的Enumerable的模块的each方法。在这里阐述是为了展示第一个传入的参数的结构与迭代的顺序。

作为用于迭代的第一个参数的数据对是以一个有两个下列属性的对象来被传递的：

  1. key：是一个字符串形式的键名。
  2. value：是相应的值(可以是undefined)。

迭代的顺序是浏览器相关的，因为它依靠的是for..in循环。虽然这个迭代会忽略Hash与Enumerable方法(天然地)，更准确的说，它会忽略对象上发现的属性，但是在一个哈希里有函数也是可能的。

示例

var h = $H({ version: 1.5, author: 'Sam Stephenson' });
h.each(function(pair) {
alert(pair.key + ' = "' + pair.value + '"');
});
// Alerts, in non-guaranteed order, ''version = "1.5"' and 'author = "Sam
Stephenson"'.


inspect::Hash

inspect() -> String返回hash形式的面向调试的字符串表示。

更多的关于inspect的信息，参看Object.inspect。

示例

$H({ name: 'Prototype', version: 1.5 }).inspect()
// -> "<#Hash:{name: 'Prototype', version: 1.5}>" // Order not guaranteed


keys::Hash

keys() -> [String...]给出哈希的键(即属性名)数组。

注意：名字的顺序是浏览器相关的(基于for..in循环)。同时函数属性被忽略了(比如hash方法)。

示例

$H({ name: 'Prototype', version: 1.5 }).keys().sort()
// -> ['name', 'version']

$H().keys()
// -> []


merge::Hash

merge(hash) -> alteredHash把传入的哈希的数据对注入到当前的哈希中，然后返回。

相同的键值会导致改写的问题(这里hash会占先)，并且参数hash的新键也会被使用。这对于选择性的改写特定键的值很有用(比如可以在一系统的选择里设置一些级别控制).

这个参数不一定是Hash对象，因为它会被传给$H函数来保证兼容性。

示例

var h = $H({ name: 'Prototype', version: 1.5 });
h.merge({ version: '1.5 final', author: 'Sam' });

h.invoke('join', ' = ').sort().join(', ')
// -> "author = Sam, name = Prototype, version = 1.5 final"


remove::Hash

remove(key) -> value
remove(key1, key2...) -> Array从哈希里删除键值，并且发回这些键值。

示例

var h = new  Hash({ a:'apple', b:'banana',
c:'coconut' })

h.remove('a', 'c')
// -> ['apple', 'coconut']
h.values()
// -> ['banana']


toQueryString::Hash

toQueryString() -> String把哈希转成是url-encoded形式的请求字符串的表示方式。

这是一种串行化的形式，为象Ajax名字空间(比如Ajax.Request)里的对象这样的事件提供复杂的参数集时非常有用。

未定义-值对会被串行化成空值。数组-值对会被串行化成第一个元素一个名字/值对。所有值都会被Javascript自己的encodeURIComponent函数编码成URI-encoded的形式。

除了基于数组的数据对外是按数组里的顺序串行化的，其它的数据对的串行化的顺序是不保证的(大部分情况下是无关的)。

示例

$H({ action: 'ship', order_id: 123, fees: ['f1', 'f2'], 'label': 'a demo' }).toQueryString()
// -> 'action=ship&order_id=123&fees=f1&fees=f2&label=a%20demo'

$H().toQueryString()
// -> ''

注意

这个方法可以有两种调用方式：作为实例的方法(上面的例子)或者作为Hash的类方法。

Hash.toQueryString({ foo:'bar' })
// -> 'foo=bar'

这种方法可以让你在不转化对象的情况下为这个对象产生一个查询字符串，让有Enumerable方法名的哈希对象也能被串行化。


values::Hash

values() -> Array把哈希的值以数组的形式返回。

值的顺序是浏览相关的(基于for..in循环), 所以，虽然大部分情况下你看到它是一致的，但是你最好不要依赖于特定的顺序。当然也要记住哈希可能会包含null和undefined。

示例

$H({ name: 'Prototype', version: 1.5 }).values().sort()
// -> [1.5, 'Prototype']

$H().values()
// -> []


After::Insertion

new Insertion.After(element, html)把html作为element的下一个兄弟插入到页面中。

示例

原始HTML：

<div>
<p id="animal_vegetable_mineral">In short, in all things vegetable, animal, and mineral...</p>
</div>

Javascript：

new Insertion.After('animal_vegetable_mineral', "<p>I am the very model of a modern major general.</p>");

结果HTML：

<div>
<p id="animal_vegetable_mineral">In short, in all things vegetable, animal, and mineral...</p>
<p>I am the very model of a modern major general.</p>
</div>


Before::Insertion

new Insertion.Before(element, html)把html作为element的前一个兄弟插入到页面中。

示例

原始HTML：

<div>
<p id="modern_major_general">I am the very model of a modern major general.</p>
</div>

Javascript：

new Insertion.Before('modern_major_general', "<p>In short, in all things vegetable, animal, and mineral...</p>");

结果HTML：

<div>
<p>In short, in all things vegetable, animal, and mineral...</p>
<p id="modern_major_general">I am the very model of a modern major general.</p>
</div


Bottom::Insertion

new Insertion.Bottom(element, html)把html作为element的最后一个儿子插入到页面中。

示例

原始HTML：

<div id="modern_major_general">
<p>In short, in all things vegetable, animal, and mineral...</p>
</div>

Javascript：

new Insertion.Bottom('modern_major_general', "<p>I am the very model of a modern major general.</p>");

结果HTML：

<div id="modern_major_general">
<p>In short, in all things vegetable, animal, and mineral...</p>
<p>I am the very model of a modern major general.</p>
</div>


Insertion

Insertion提供了跨浏览器的HTML片段(或者纯文本)插入的解决方案.由四个部分组成:After, Before, Bottom和Top,它们的行为与名字是相同的.

模块索引
After
new Insertion.After(element, html)

把html作为element的下一个兄弟插入到页面中。

Before

new Insertion.Before(element, html)

把html作为element的前一个兄弟插入到页面中。

Bottom

new Insertion.Bottom(element, html)

把html作为element的最后一个儿子插入到页面中。

Top

new Insertion.Top(element, html)

把html作为element的第一个儿子插入到页面中。


Top::Insertion

new Insertion.Top(element, html)把html作为element的第一个儿子插入到页面中。

示例

原始HTML：

<div id="modern_major_general">
<p>In short, in all things vegetable, animal, and mineral...</p>
</div>

Javascript：

new Insertion.Top('modern_major_general', "<p>I am the very model of a modern major general.</p>");

结果HTML：

<div id="modern_major_general">
<p>I am the very model of a modern major general.</p>
<p>In short, in all things vegetable, animal, and mineral...</p>
</div>


Number

Prototype扩展了原生的Javascript的Number，实现了以下功能：

  • 通过succ方法，实现与ObjectRange的兼容。
  • 通过times方法，实现了与Ruby相似的数字循环。
  • 实现了象toColorPart这样简单的功能方法。
内容导航
  • 什么变成了可能？
  • 模块索引
什么变成了可能？

 $R(1, 10).each(function(index) {
// This gets invoked with index from 1 to 10, inclusive
});

(5).times(function(n) {
// This gets invoked with index from 0 to 5, *exclusive*
// The parentheses are due to JS syntax, if we did not use a literal, they'd be
superfluous
});

128.toColorPart()
// -> '70'

10.toColorPart()
// -> '0a'

'#' + [128, 10, 16].invoke('toColorPart').join('')
// -> '#800a10'

模块索引
succ
succ() -> Number

返回当前值(current)的下一个定义为当前值(current + 1)。用于让数值与ObjectRange兼容。

times

times(iterator) -> Number

封装一个规则的[0..n]的循环，Ruby风格。

toColorPart

toColorPart() -> String

产生一个两位十六进制的表示，假设原数字是[0..255]范围内。对于CSS色彩的字符串组合很有用。

toPaddedString

toPaddedString(length[, radix]) -> String

将一个数值转成一个由0填充的字符串，让字符串的长度至少等于length。radix可选项用于指定数值的基。


succ::Number

succ() -> Number返回当前值(current)的下一个定义为当前值(current + 1)。用于让数值与ObjectRange兼容。

示例

(5).succ()
// -> 6

$A($R(1, 5)).join('')
// -> '12345'


times::Number

times(iterator) -> Number封装一个规则的[0..n]的循环，Ruby风格。

这个回调函数用一个参数来调用，这个参数的值从0到这个Number的值进行变化，专用。

示例

var s = '';
(5).times(function(n) {
s += n;
});

s
// -> '01234'


toColorPart::Number

toColorPart() -> String产生一个两位十六进制的表示，假设原数字是[0..255]范围内。对于CSS色彩的字符串组合很有用。

示例

128.toColorPart()
// -> '70'

10.toColorPart()
// -> '0a'

'#' + [128, 10, 16].invoke('toColorPart').join('')
// -> '#800a10'


toPaddedString::Number

toPaddedString(length[, radix]) -> String将一个数值转成一个由0填充的字符串，让字符串的长度至少等于length。radix可选项用于指定数值的基。

示例

138.toColorPart()
// -> '70'

10.toColorPart()
// -> '0a'

'#' + [128, 10, 16].invoke('toColorPart').join('')
// -> '#800a10'
(13).toPaddedString(4);
// -> '0013'

(13).toPaddedString(2);
// -> '13'

(13).toPaddedString(1);
// -> '13'

(13).toPaddedString(4, 16)
// -> '000d'

(13).toPaddedString(4, 2);
// -> '1101'


clone::Object

Object.clone(obj) -> Object通过表面的复制来克隆这个传入的对象(只复制所有的原始的属性到结果里)

示例

var o = { name: 'Prototype',
version: 1.5, authors: ['sam', 'contributors']
};
var o2 = Object.clone(o);

o2.version = '1.5 weird';
o2.authors.pop();

o.version
// -> 1.5

o2.version
// -> '1.5 weird'

o.authors
// -> ['sam'] // Ouch! Shallow copy!


Object

Object是被Prototype当成是命名空间来用的。也就是说，他包含了一些新的方法，而这些方法是有意要通过一个名字空间来访问的(比如以"Object'开头)。

对于普通的开发者(那些只是简单的使用Prototype而不进行修改的)来说，最常用的方法可能就是inspect，次之是clone。

对于想象Prototype那样创建自己的对象或者把对象当成是哈希来检查的高级用户来说，可能extend，keys和values会更加常用。

模块索引
clone
Object.clone(obj) -> Object

通过表面的复制来克隆这个传入的对象(只复制所有的原始的属性到结果里)

extend

Object.extend(dest, src) -> alteredDest

从源对象复制所有的属性到目的对象.被Prototype拷贝到prototype里用来模拟继承(不是静态实现的).

inspect

Object.inspect(obj) -> String

返回面向调试的用于表示对象的字符串。

keys

Object.keys(obj) -> [String...]

把所有的对象当成是一个Hash，然后得到对象的属性名字列表。

values

Object.values(obj) -> Array

把所有的对象当成是一个Hash，然后得到对象的属性值列表。

toJSON

toJSON() -> String

返回一个JSON字符串。


extend::Object

Object.extend(dest, src) -> alteredDest从源对象复制所有的属性到目的对象.被Prototype拷贝到prototype里用来模拟继承(不是静态实现的).

Object.extend函数将第二个对象的属性补到第一个对象中，实际上就是把他们拼起来。

Object.extend(objA, objB); // Amends objA with objB

函数返回变化后的objA，以方便直接使用或者供函数调用。 对象objB里的属性将会复盖掉objA里的相同名字的属性。

在script.aculo.us里Object.extend的一个常见的用法是接受用户自己定义改写的属性更新默认的选项。

示例

基本用法：

objA = {name: "Joe", age: "12"};
objB = {name: "Tom"};

Object.extend(objA, objB);

objA.name
// -> "Tom"

含赋值的用法：

objA = {name: "Joe", age: "12"};
objC = Object.extend(objA, {name: "Tom"});
objD = Object.extend(objA, {name: "Jim"});

objC.name
// -> "Tom"

objD.name
// -> "Jim"

// Note that objA always gets changed
objA.name
// -> "Jim

注意

这个官方的文档还没有完全完成。上面的这些是从script.aculo.us的wiki上取过来的，由Thomas Fuchs创建.

不要与名字有些相同的Element.extend混淆了。那可是更加复杂的对于DOM的扩展。


inspect::Object

Object.inspect(obj) -> String返回面向调试的用于表示对象的字符串。

  • undefined和null返回本身
  • 其它的类型先查找inspect方法，如果有，就调用inspect。否则调用toString方法

Prototype提供了对多种数据类型的支持，包括内建的和库定义的，比如String, Array, Enumerable和Hash,它试图提供相应类型最有用的字符串表示(从程序员角度来看)。

示例

Object.inspect()
// -> 'undefined'

Object.inspect(null)
// -> 'null'

Object.inspect(false)
// -> 'false'

Object.inspect([1,
2,
3])
// -> '[1, 2, 3]'

Object.inspect('hello')
// -> "'hello'"


keys::Object

Object.keys(obj) -> [String...]把所有的对象当成是一个Hash，然后得到对象的属性名字列表。

注意到结果数据的顺序是浏览器相关的(它依据for..in循环)，因此不能保证它是根据声明的顺序或者是字母的顺序。如果你想保证顺序，你需要对数据进行排序。

示例

Object.inspect()
// -> 'undefined'

Object.inspect(null)
// -> 'null'

Object.inspect(false)
// -> 'false'

Object.inspect([1,
2,
3])
// -> '[1, 2, 3]'

Object.inspect('hello')
// -> "'hello'"


toJSON::Object

toJSON() -> String返回一个JSON字符串。

  • undefined和null返回本身
  • 其它的类型先查找inspect方法，如果有，就调用inspect。否则调用toString方法

Prototype提供了对多种数据类型的支持，包括内建的和库定义的，比如String, Array, Enumerable和Hash,它试图提供相应类型最有用的字符串表示(从程序员角度来看)。

示例

var data = {name: 'Violet',
occupation: 'character', age:
25, pets: ['frog', 'rabbit']};
Object.toJSON(data);

//-> '{"name":"Violet","occupation":"character","age":25,"pets":["frog","rabbit"]}'


values::Object

Object.values(obj) -> Array把所有的对象当成是一个Hash，然后得到对象的属性值列表。

注意到结果数据的顺序是浏览器相关的(它依据for..in循环)，因此不能保证它是根据声明的顺序或者是字母的顺序。同时要记录的是属性名是唯一的，所以属性值是没有限制的。

示例

Object.values()
// -> []

Object.values({ name: 'Prototype', version: 1.5 }).sort()
// -> [1.5, 'Prototype']


ObjectRange

范围代表的是一个值段。这个值类型需要是兼容的。也就是说，要实现一个succ方法让我们可以对一个值步进到下一个值(它的后继者).

Prototype给Number和String提供了一个这样的方法。但是你当然也可以根据你自己的语义来实现你自己的对象的范围处理。

ObjectRange与Enumerable混合起来，让范围变得非常多变。但为了更好的性能，改写默认的include代码时一定要小心。

虽然ObjectRange提供了构造函数，推荐的创建一个范围的方法是使用$R这个工具函数。它们的差别只是$R更加简洁一点。

内容导航
  • 示例
  • 模块索引
示例

用的最多的范围，无疑是数值：

$A($R(1, 5)).join(', ')
// -> '1, 2, 3, 4, 5'

$R(1, 5).zip(['one', 'two', 'three', 'four', 'five'], function(tuple) {
return tuple.join(' = ');
})
// -> ['1 = one', '2 = two', '3 = three', '4 = four', '5 = five']

对于字符范围要注意：在succ方法中已经提到过，它并不是按字母范围作为边界的，而是以字符表的为依据的。

$A($R('a', 'e'))
// -> ['a', 'b', 'c', 'd', 'e'], no surprise there

$A($R('ax', 'ba'))
// -> Ouch! Humongous array, starting as ['ax', 'ay', 'az', 'a{', 'a|', 'a}', 'a~'...]

模块索引
include
include(value) -> Boolean

确定value是不是在范围内。


include::ObjectRange

include(value) -> Boolean确定value是不是在范围内。

这个函数假设范围是有一个有效的严格的弱的顺序(有一个有效的<运算符语义)。由于Object混入了Enumerable，这个方法改写了默认的include，并且这个方法是更加有效的(它最多更用两次比较)。

示例

Object.values()
// -> []

Object.values({ name: 'Prototype', version: 1.5 }).sort()
// -> [1.5, 'Prototype']

$R(1, 10).include(5)
// -> true

$R('a', 'h').include('x')
// -> false

$R(1, 10).include(10)
// -> true

$R(1, 10, true).include(10)
// -> false


PeriodicalExecuter

这是一个简单的用于定期执行函数的工具。它实际上封装了原生的Window对象里的clearInterval/setInterval机制。

它的明显的好处是屏闭了多个并行的回调函数的执行，所以它比给定的时间会花更长的时间执行(它维护了一个内部运行标志，并与回调函数里的异常分离开了)。这个在某个时间段内与用户交互时会特别有用(比如用prompt和confirm调用)：这个避免多个消息框等待被执行的情况 。

当然。也会有人认为使用实际的对象，不用保持一个全局的值等也会有很多好处。

内容导航
  • 创建一个PeriodicalExecuter
  • 模块索引
创建一个PeriodicalExecuter

 $R(1, 10).each(function(index) {
// This gets invoked with index from 1 to 10, inclusive
});

(5).times(function(n) {
// This gets invoked with index from 0 to 5, *exclusive*
// The parentheses are due to JS syntax, if we did not use a literal, they'd be
superfluous
});

128.toColorPart()
// -> '70'

10.toColorPart()
// -> '0a'

'#' + [128, 10, 16].invoke('toColorPart').join('')
// -> '#800a10'

模块索引
succ
succ() -> Number

返回当前值(current)的下一个定义为当前值(current + 1)。用于让数值与ObjectRange兼容。

times

times(iterator) -> Number

封装一个规则的[0..n]的循环，Ruby风格。

toColorPart

toColorPart() -> String

产生一个两位十六进制的表示，假设原数字是[0..255]范围内。对于CSS色彩的字符串组合很有用。

toPaddedString

toPaddedString(length[, radix]) -> String

将一个数值转成一个由0填充的字符串，让字符串的长度至少等于length。radix可选项用于指定数值的基。


$:: Utility Methods

$(id | element) -> HTMLElement
$((id | element)...) -> [HTMLElement...] 如果传入的是一个字符串，那么返回DOM文档中与这个字符串匹配的ID的元素。否则返回这个元素本身。对于放进来的任何的参数，这个函数返回的所有元素都被扩展了Prototype的DOM扩展。

$方法在Prototype的方法中，就象是一把瑞士军刀。它不仅提供了一个方便的document.getElementById的别名，它还让你无差别的传ID(字符串)或者DOM节点的引用到函数中。

function foo(element) {
element = $(element);

/* rest of the function... */

这样写的代码灵活性很好——你可以传进去元素ID，也可以是元素本身，而不用管这些类型上的细节

传入一个参数返回一个元素，传入多个参数返回元素的数组(这个还可以递归：如果你想较真，你可以转一个包含有数组的数组进去，或者别的什么的。) 由于它是依赖getElementById的，所以W3C的规范起作用了：ID不存在，返回null；如果ID在DOM里出现多次，那么你会得到一些希奇古怪的东西。 如果你对多个元素用同一个ID，那么你已经错误了！

这个函数也把Element.extend扩展到了每个返回的元素，这样你就可以在它上面执行prototype的DOM扩展了。在下面的代码里，这两行代码是等价的。但是第二行显然更加面向对象。

// Note quite OOP-like...
Element.hide('itemId');

// A cleaner feel, thanks to guaranted extension
$('itemId').hide();

当然，如果使用迭代子，就可以把$函数用的更加优雅、更加简洁、并且更加高效：

['item1', 'item2', 'item3'].each(Element.hide);

// The better way:
$('item1', 'item2', 'item3').invoke('hide');


$$:: Utility Methods

$$(cssRule...) -> [HTMLElement...] 接受任意个数的CSS选择器(字符串)，返回一个满足条件的按文档排序的已经被扩展的DOM元素的数组。

有时候，一些常用的DOM工具函数，象被$()封装的document.getElementById()、getElementsByTagName()或者即便是Prototype自己的getElementsByClassName()也不能很快找到我们要的元素或者元素的集合。如果你了解DOM树的结构，你可以简单的通过CSS选择器来把这件事情处理掉。

性能：什么时候我们不应该使用$$()函数

现在我们看到，这个函数的功能是强大的。但是如果被误用，它会导致性能上的问题。所以下面是一些指导：

  • 如果你在许多类名里寻找一个特定的CSS类元素集，你可以使用Prototype的document.getElementsByClassName()扩展。
  • 当然，更好的情况是：如果你是在一个容器里查找，你可以使用Element.getElementsByClassName() 扩展。

对于一些简单的基于CSS类的查找，我们倾向于这些方法，至少他们的速度比$$快。对于一些支持DOM等级3的XPath的浏览器，这个函数的速度简直是飞快！

但是如果你想对更加复杂的东西进行处理，那么用$$。但是要用好它。$$函数默认搜索整个文档。 所以如果你能够做到的话，尽量缩小你的搜索范围。比如让它们以ID选择器开头，那样可以尽快的减少搜索树，加快运行速度。

示例

$$('div')
// -> all DIVs in the document. Same as document.getElementsByTagName('div')!

$$('#contents')
// -> same as $('contents'), only it returns an array anyway.

$$('li.faux')
// -> all LI elements with class 'faux'

$$('#contents a[rel]')
// -> all links inside the element of ID "contents" with a rel attribute

$$('a[href="#"]')
// -> all links with a href attribute of value "#" (eyeew!)

$$('#navbar li', '#sidebar li')
// -> all links within the elements of ID "navbar" or "sidebar"

支持的CSS语法

$$函数不依赖于浏览器内部的CSS解释能力(否则我们会有跨浏览器的问题...)，因此能提供所有浏览器一致的选择器。一个小问题是，它现在还不能象浏览器一样提供对任何CCS能力的支持。

这里是当前支持的CSS选择器的形式：

  • 类型选择器：标签名，象div。
  • 后代选择器：两个选择器之间有空格，象#a li。
  • 属性选择器：所有的CSS2.1的规定的属性选择器，象[attr]，[attr=value]，[attr~=value]和[attr|=value]。它也支持[attr!=value]。
    如果你要匹配的值包含有空白字符，一定要记得把这个值放在引号中间([title=”Hello World!”])。
  • 类选择器：CSS类名，象.hightlighted或者.example.wrong
  • ID选择器：象#item1

然而，现在它没有支持子选择器(>)，邻居选择器(+)，伪元素(:after)，伪类(:hover)。


$A:: Utility Methods

$A(iterable) -> actualArray 接受一个与数组类似的集合(都有数字化的索引)，返回与它相等的真正的数组对象。这个方法是Array.from的一个方便的别名，但是却是我们推荐的转化数组的方法 。

$A()函数最基本的作用就是得到一个真正的Array对象，基于任何可以被当成数组传递的东西(例如：NodeList或者HTMLCollection对象由很多DOM方法返回，或者在你的函数里预先定义的参数引用)。

你需要一个真正的Array对象的原因可能很简单:因为Prototype给Array扩展了大量的方法，同时还加进了Enumerable模块，这个模块又带来了一大批好用的方法。因此在Prototype里，真正的Array对象比任何其它的你可能从其它方法得到的集合类型都要好用。

所执行的转换可能相当的简单：null, undefined和false如果是一个空数组的话；任何对象附加有一个显式的toArray方法(象不少Prototype对象一样)的，直接调用它；否则，我们假设这个参数”象一个数组“(比如有长度与[]操作符)，然后常规去遍历它的各个组成部分。

示例

非常有名的DOM方法document.getElementsByTagName并不返回数组，但是NodeList对象实现了基本的数组”接口“。Internet Explorer不允许我们把Enumerable扩展到NodeList.prototype上，所以我们把返回的NodeList转化成一个数组：

var paras = $A(document.getElementsByTagName('p'));
paras.each(Element.hide);
$(paras.last()).show();

注意到我们必须使用Element.hide()，因为$A()并不执行DOM扩展的动作，因为这个数组里面可能包含任何东西(不仅只是DOM元素)。做hide这个实例方法，以确保我们的目标元素都已经被扩展了。

$A(document.getElementsByTagName('p')).map(Element.extend).invoke('hide');

想很方便的打印你的参数吗？所有的Array都有一个join方法，但是所有函数里的所有参数值并没有继承于Array。所以要难一点的办法，还是简单一点的办法

// The hard way...
function showArgs() {
alert(Array.prototype.join.call(arguments, ', '));
}

// The easy way...
function showArgs() {
alert($A(arguments).join(', '));
}


$F:: Utility Methods

$F(element) -> value 返回一个FROM控件的值。这是Form.Element.getValue的一个方便的别名。细节参考这个方法。


$H:: Utility Methods

$H([obj]) -> EnumerableHash 唯一的一个得到哈希表(从我们的观点上讲它与MAP和联合数组是相同的)的办法。返回一个新的对象，带上了Hash与Enumerable模块的所有特征。如果传入一个原始的对象，会在与模块混合前先把所有的属性克隆好 。

$H()函数是得到哈希的唯一办法。

事实上，Hash是一个模块，而不是一个类。在Prototype的类机制里，执行new Hash()是没有用的；它将会引起一个”Hash不是一个构造器“的错误。

这个Hash模块设计的目的是想把它混进已经混有Enumerable的对象中去。所以$H函数保证给你的是将两个都已经混好的对象

你可以调用$H()而不传入任何参数：你会得到一个空的哈希（也就是只是混好了这些方法的东西）。如果你传入一个参数，它先克隆这个转入参数，然后混入这些模块。任何与混入的模块的方法相冲突的名字都会被删除。

现在有一个来自亲爱的Mislav的没有完全确定的补丁,它提供了一个”安全的哈希“。能使用任何键名，没有任何冲突的风险或者语法限制。如果这个补丁被加入，这个页面会跟着更新。


$R:: Utility Methods

$R(start, end[, exclusive = false]) -> ObjectRange 创建一个新的ObjectRange对象。这个方法是对ObjectRange构造函数的一个方便的封装，但这个方法是推荐的 。

ObjectRange实例代表了一系例相关的值，它们可能是数值的，文本的或者其它语义上支持值范围的。你可以查看类型文档得到更详细的说明，以及你自己的对象怎样才能支持值范围。

$R函数与原始的构造函数所需要的参数是一样的：最小与最大范围(同一类型的)，以及最大范围是否包括。默认情况下，最大范围是包括的。

示例

$R(0, 10).include(10)
// -> true

$A($R(0, 5)).join(', ')
// -> '0, 1, 2, 3, 4, 5'

$A($R('aa', 'ah')).join(', ')
// -> 'aa, ab, ac, ad, ae, af, ag, ah'

$R(0, 10, true).include(10)
// -> false

$R(0, 10, true).each(function(value) {
// invoked 10 times for value = 0 to 9
});

注意到ObjectRange混入了Enumerable模块：这就让一个范围转成一个Array变得容易了(Enumerable提供了toArray方法让$A的转变很直接)或者很容易的遍历各个值。

注意

注意，不管怎样，使用start或者end属性会比调用min()与max()方法找范围来的更快。


$w:: Utility Methods

$w(String) -> Array 把字符串拆分成一个数组，把所有的空白字符当成里分界符。与Ruby的 %w{foo bar}或者Perl的qw{foo bar}相同。

这是给那些不喜欢用常量数组的逗号的人做的一个便利品。

示例

$w('apples bananas kiwis')
// -> ['apples', 'bananas', 'kiwis']

它可以在写一些简单的循环时节省一些代码：

$w('apples bananas kiwis').each(function(fruit){
var message = 'I like ' + fruit
// do something with the message
})

再与Element的函数结合起来，它也很好用：

$w('ads navbar funkyLinks').each(Element.hide);


常用方法

Prototype提供了大量方便的方法。大部分是别的方法的别名；但$()函数不是，$()函数对DOM元素进行了封装并增加了额外的功能。

这些公共方法因为经常被使用，它们的名字需要尽可能的简洁，所以就有了基于$的惯例。

这些方法里面最常用的毫无疑问是$()，它被普遍用于Prototype的代码里面，你可以传元素的ID或者一个真实元素的引用，当然我们要能找到这个引用。它并不只是一个对于document.getElementById的简单封装，下面我们一起来看一下它有多有用。

这些方法都是高效编写基于Prototype的javascript代码的基础。

学习它们得花点时间。

主题索引
$
$(id | element) -> HTMLElement
$((id | element)...) -> [HTMLElement...]

如果传入的是一个字符串，那么返回DOM文档中与这个字符串匹配的ID的元素。否则返回这个元素本身。对于放进来的任何参数，这个函数返回的所有元素都被扩展了Prototype的DOM扩展。

$$
$$(cssRule...) -> [HTMLElement...]

接受任意个数的CSS选择器(字符串)，返回一个满足条件的按文档排序的已经被扩展的DOM元素的数组。

$A
$A(iterable) -> actualArray

接受一个与数组类似的集合(都有数字化的索引)，返回与它相等的真正的数组对象。这个方法是Array.from的一个方便的别名，但是却是我们推荐的转化数组的方法。

$F
$F(element) -> value

返回一个表单控件的值。这是Form.Element.getValue的一个方便的别名。细节参考这个方法。

$H
$H([obj]) -> EnumerableHash

唯一的一个得到哈希表(从我们的观点上讲它与MAP和联合数组是相同的)的办法。返回一个新的对象，带上了Hash与Enumerable模块的所有特征。如果传入一个原始的对象，会在与模块混合前先把所有的属性都复制好。

$R
$R(start, end[, exclusive = false]) -> ObjectRange

创建一个新的ObjectRange对象。这个方法是对ObjectRange构造函数的一个方便的封装，但这个方法是推荐的。

$w
$w(String) -> Array

把字符串拆分成一个数组，把所有的空白字符当成里分界符。与Ruby的 %w{foo bar}或者Perl的qw{foo bar}相同。

Try.these
Try.these(Function...) -> firstOKResult

接收任意数量的函数，返回最前面的一个没有异常的函数。

document.getElementsByClassName
document.getElementsByClassName(className[, element]) -> [HTMLElement...]

接收(扩展)所有的含有className的CSS类名的元素。可选项element是搜索的父节点元素。


getElementsByClassName:: Utility Methods

document.getElementsByClassName(className[, element]) -> [HTMLElement...] 接收(扩展)所有的含有className的CSS类名的元素。可选项element是搜索的父节点元素。

要注意的是所有的返回的元素都已经被扩展了。

示例

HTML

<body>
<div id="one" class="foo">Single class name</div>
<div id="two" class="foo bar thud">Multiple class names</div>
<ul id="list">
<li id="item_one" class="thud">List item 1</li>
<li>List item 2</li>
<li id="item_two" class="thud">List item 3</li>
</ul>
</body>

JavaScript:

document.getElementsByClassName('foo');
// -> [HTMLElement, HTMLElement] (div#one, div#two)

document.getElementsByClassName('thud');
// -> [HTMLElement, HTMLElement, HTMLElement] (div#two, li#item_one, li#item_two);

document.getElementsByClassName('thud', $('list'));
// -> [HTMLElement, HTMLElement] (li#item_one, li#item_two)


Try.these:: Utility Methods

Try.these(Function...) -> firstOKResult 接收任意数量的函数，返回最前面的一个没有异常的函数。

要注意的是所有的返回的元素都已经被扩展了

这个方法提供了一个简单的规格方法，让各块代码顺序的被测试。这个尝试的顺序通常是得到一种给定的特性的下降的方法。

在这个来自Prototype的Ajax库的例子里，我们想得到XMLHttpRequest作为一个对象。Internet Explorer 6或者更早没有提供这个对象，并且会抛出一个异常，如果我们试图去创建一个。并且，随着时间的变化，它的私有的创建办法也变了，COM接口名变了。

Try.these将会顺序测试几个方法，从最好的(理论上，最通用)的到最老的并且最少用的方法，返回第一个成功的函数的结果。

如果没有一个模块是成功执行的，Try.these会返回undefined.在这时它会导致getTransport方法返回false，这个值当成是失败的返回值。

getTransport: function() {
return Try.these(
function() { return new XMLHttpRequest() },
function() { return new ActiveXObject('Msxml2.XMLHTTP') },
function() { return new ActiveXObject('Microsoft.XMLHTTP') }
) || false ;
}