基本模块问题在这里:如果我放弃使用模块模式,我可以很好地让全局处理程序正常工作,但是这个测试代码不起作用,我很难找出原因。
var MyModule = (function($, my) {
$(my).ajaxStart(function() { window.alert("ajax start"); });
$(document).ready(function() {
$.ajax(SOME_AJAX_SETTINGS_HERE);
});
return my;
}(jQuery, MyModule || {}));
当ajax调用执行时,附加到MyModule
实例的处理程序从未运行。如果我改为将处理程序附加到$(document)
,那么它就可以正常工作,但是我很好奇为什么全局事件似乎无法正确地绑定到模块对象。
编辑:这里有一个更简单的示例:
var x = {};
$(x).ajaxStart(function() { window.alert("foo"); } );
$.ajax(SOME_AJAX_SETTINGS);
如果我用
$(document)
来代替$(x)
,它就能正常工作了...这似乎只是因为我不能将ajaxStart
(或其他全局ajax事件)绑定到非DOM对象上?
@Nucleon,我认为这并不完全正确,下面是一个例子:
var item = {foo: function() { window.alert("shorthand"); } };
$(item).bind("foo", function () { window.alert("longhand"); } );
window.alert("about to trigger (locally)");
$(item).trigger("foo");
window.alert("now we triggerHandler (locally)");
$(item).triggerHandler("foo");
这里,自定义事件“foo”通过两个模式进行绑定,不同的触发方法显示出模式的特异性...您将会收到两次“longhand”警报和一次“shorthand”警报。
现在,您也可以使用$.event.trigger("foo")
来触发全局事件(但是,没有相应的全局triggerHandler
存在)。
问题是如果您添加以下代码:
window.alert("now we trigger (globally)");
$.event.trigger("foo");
对于此全局事件触发,两个处理程序都不会运行。
然而,如果您将item
替换为某个DOM类型的元素--正如您上面所建议的--那么本地和全局事件都会被处理,但缩写处理程序现在将无法工作*。因此,似乎虽然本地处理适用于非DOM对象,但是特别是全局处理不起作用。
-m
*缩写处理程序停止工作,因为缩写模式仅适用于非DOM对象。我个人认为,这种非DOM对象的“缩写”行为应该从jQuery中删除。很少有人知道它,而且它只在全局jQuery对象页面上的一个晦涩的句子中记录...它的行为可能会让不知情的人感到疯狂,因为它隐含地执行了一个绑定步骤,这是人们可能不知道的。
啊,好的...$.event.trigger
功能不是公开的,尽管它被底层的事件触发机制使用。我想我只是不应该使用它。
事实证明,这种行为对于jQuery开发人员来说是具有挑战性的,而且看起来他们正在完全放弃它(或者这就是我从这个被标记为“已修复”的错误报告中获得的信息:DEPRECATE AJAX "GLOBAL" EVENT BEHAVIOR)。
但是,我仍然有些困惑于.trigger
被记录为对DOM或非DOM对象具有相同的行为方式,因为只有以下一种警报会运行:
var plain = {foo: function() { window.alert("plain"); } };
var dom = $("<div></div>");
dom.foo = function() { window.alert("dom"); };
console.log(plain.foo); // make sure we see function foo on the plain object.
console.log(dom.foo); // now make sure we see function foo on the DOM object.
$(plain).trigger("foo"); // raises the "plain" window alert.
$(dom).trigger("foo"); // raises no alert.
我猜这意味着在控制台检查对象时,设置在dom上的foo属性实际上并不是传统意义上的“正确”JS属性(尽管它显示正确)? 注意:现在这都是为了知识而言——因为我将遵循上面bug链接中的“修复”建议,并将所有我的AJAX(和其他全局)事件绑定到document上,因为它似乎是jQuery 1.9中强制执行的行为。但我已经服用了蓝色药丸,感觉自己已经深入兔子洞而无法爬出来。
$.trigger()
的说明:对于普通对象和DOM对象,如果触发的事件名称与对象上的属性名称匹配,jQuery将尝试将该属性作为方法调用,如果没有事件处理程序调用event.preventDefault()。如果不希望出现这种行为,请改用.triggerHandler()。
此外,我不知道$.event.trigger("foo")
甚至是做什么的,我在文档中找不到这样的调用。 - Owen Allen