TypeError: $(...).on is not a function with prototype.js

TypeError: $(...).on is not a function with prototype.js

我想为表单的子项的更改事件添加过滤侦听器,但我从 $ 选择器中得到奇怪的结果。

我用 $("exportForm") 形式的 ID 调用选择器并尝试调用它的 .on(...) 方法,得到了有问题的错误。

检查返回的元素,我似乎找到了一个以数字作为 ownProperties 名称的数组。在控制台中索引它们 $(...)[1] returns 表单的单个子项。在 proto 属性 中似乎没有任何应该由选择器添加的 Prototype.js 方法的踪迹。

出了什么问题?要让它正常工作需要注意什么?

PS: Prototype.js 版本为 1.6.1

你是对的。 on()是1.7加入的,所以这里不能用。 on 方法给你的是 "lazy evaluation"。当你打电话给

$(document).on('eventName', 'css selector', function(){ ... });

...您得到一个观察者,它不必在页面加载后或页面的某些部分被 Ajax 回调替换后进行初始化。您可以替换页面的一部分,然后再次单击它,观察器就会正常工作。

设置观察者的旧方法是这样的:

$(document).observe('dom:loaded', function(){
  $('theId').observe('eventName', function(){
    // do something
  });
});

外部观察者等待页面加载完成,然后内部观察者观察某个对象的事件并对其进行处理。这将起作用,只要 DOM 在加载后没有改变。如果发生这种情况,那么您必须手动重新注册内部侦听器,因为它的目标已更改,并且不再有效。 dom:loaded 事件仅在页面本身第一次加载时触发一次。

在你的例子中,你似乎想复制 Prototype 中 Form.Element.Observer() class 方法的行为,它设置了一个表单的所有子元素的定时轮询,并触发一个当其中任何一个发生变化时回调。您真的应该查看该方法的文档,因为它是一种真正可靠的方法来完成您想要做的事情。但是如果你真的想自己动手,下面是你如何编写一个可以监听多个元素事件的观察者:

$(document).observe('dom:loaded', function(){
  $$('#exportForm input').invoke('observe', 'change', function(evt, elm){
    // evt is the event itself, you can cancel, log, whatever
    // elm is a reference to the form element, you can do elm.getValue(), etc.
  });
});

这使用 "double-dollar" 方法获取元素数组,因此捕获 ID 为 exportForm 的表单内的任何表单输入。

invoke() 将相同的回调和参数应用于元素数组,因此这是为每个表单元素设置一个单独的 observe 方法——如果您有大量输入则效率不高!您可以尝试在表单本身上监听 change 事件,因此您只有一种观察者方法,但根据您需要支持的浏览器,您可能会发现这些事件并不总是从个人冒泡表单输入到表单本身。你得仔细测试一下。

观察到的每个表单元素都将被孤立地看到:您将无法从回调中访问其余的表单输入,只能访问那个。

这就是 Form.Element.Observer 如此强大的原因 -- 它每次触发时都会为您提供整个表单的哈希值,因此您可以执行诸如创建预览或验证之类的操作,足够频繁地显示"live".