observe
Event.observe(element, eventName, handler[, useCapture = false])
在 DOM 元素上注册事件处理程序。
重要提示
首先,如果你曾经使用过 HTML 事件属性(如 <body onload="return myFunction()">
)或 DOM Level-0
的事件属性(如 window.onload = myFunction;
),你一定要忘记那些糟糕的做法,然后了解 observe
是怎么做的。
对于那些相同的元素事件(element+event)组合,它并不会替换已经存在的事件处理程序,而是将新的处理程序增加到元素事件组合的
处理程序列表 中。使用 observe
再也不会影响到先前已有的事件处理程序调用了。
参数说明
- 对于希望增加事件处理的 DOM 元素:按照 Prototype 的一贯原则,可以使用一个真实的 DOM 节点引用,也可以使用元素的 ID 字符串。
- 根据浏览器所支持的 DOM 级别(通常支持 DOM Level 2 事件,详细的事件名称及细节请查看 1.6 节),采用相应的标准化的事件名称。这就像 'click' 一样简单易用。
- 事件处理函数可以是一个匿名函数、一个普通的函数或是一个 作为事件侦听器的绑定函数,这取决于你。
- 可选的,可以使用 捕获(capturing)来阻止事件 冒泡(bubbling),关于这两个概念,DOM 规范中有详细的描述。注意 捕获 在个别主流的浏览器上并不支持,但是这个参数也很少会用到。通常情况下, 根本不需要使用这个参数。
经常忘记的一个前提条件…
为注册函数作为事件处理程序,相关的 DOM 元素必须已经存在于 DOM 树中(换句话说,该元素必须出现在 HTML 源代码中,或者在注册事件处理程序的代码运行前,已动态的创建和插入到 DOM 中)。
一个简单的样例
假设有以下 (X)HTML 片断:
<form id="signinForm" method="post" action="/auth/signin">… </form>
下面的代码描述了如何在表单提交事件上注册函数 checkForm
:
Event.observe('signinForm', 'submit', checkForm);
当然,你会希望这行代码运行时,表单已存在于 DOM 中。但是在文档 <head> 以外的地方放置一对 <script> 标签实在有碍观瞻,因此请使用一种简单的方式来代替——在页面完全载入后再加载处理程序:
Event.observe(window, 'load', function() {
Event.observe('signinForm', 'submit', checkForm);
});
只增加了一点点封装…
注意,如果页面非常大,你可能希望在页面未完全载入前就运行这段代码(只需等待相应的 DOM 节点载入)。目前没有标准的事件支持这样做, 但是这篇文章指出了一些有用的方法。
需要使用 this
引用的复杂情形
当你的事件处理程序作为函数参数传递时,会失去事件处理函数的 绑定。也就是说,会失去原始的事件处理函数中
this
所指向的对象。如果你所传递的方法需要使用 this
引用(例如访问 this
所表示的容器对象中的字段),这会有一些麻烦。
为解决这个问题,Prototype 专门提供了一个 bindAsEventListener 方法, 如果你以前未曾见过,请查阅相关的文档。该方法的使用非常简单:
var Checks = {
// 我们的 'generic' 函数所需的一些信息
generic: function(event) {
// 表单校验逻辑(例如非空字段校验)
}
};
Event.observe('signinForm', 'submit', Checks.generic.bindAsEventListener(Checks));
参见
stopObserving 和 unloadCache 方法。