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".
我想为表单的子项的更改事件添加过滤侦听器,但我从 $ 选择器中得到奇怪的结果。
我用 $("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".