这里的基本模块问题:如果我放弃我的模块模式,我可以让全局处理程序正常工作,但是这个测试代码不起作用,我很难弄清楚为什么:
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);
如果我替换$(x)
为$(document)
,它可以工作......似乎我无法将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”通过两种模式绑定,并且不同的触发方法显示模式特异性......您将获得两次“普通”警报和一次“速记”警报。
$.event.trigger("foo")
现在,您还可以使用(但是,不存在等效的全局)来触发全局事件triggerHandler
。问题是如果您将此代码添加到末尾:
window.alert("now we trigger (globally)");
$.event.trigger("foo");
两个处理程序都不会针对此全局事件触发运行。
但是,如果您item
用一些 DOM 类型的元素替换 - 正如您在上面建议的那样 - 那么本地和全局事件都会被处理,但需要注意的是“速记”处理程序现在不起作用*。所以看起来虽然本地处理适用于非 DOM 对象,但它特别是全局处理不起作用。
-m
*速记处理程序停止工作,因为速记模式仅适用于非 DOM 对象。我个人认为应该从 jQuery 中删除非 DOM 对象的这种“速记”行为。很少有人知道它,而且它只记录在全局 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.
我想这意味着foo
设置的属性dom
实际上并不是传统意义上的“正确”JS 属性(尽管在控制台上检查对象时它正确显示)?
注意:现在这一切都是为了知识 - 因为我将只接受上面错误链接中“修复”的建议,并将我所有的 AJAX(和其他全局)事件附加到document
,因为它出现了将是 jQuery 1.9 中的强制行为。但我已经服用了蓝色药丸,感觉自己离兔子洞太远了,无法爬出来。