3

这里的基本模块问题:如果我放弃我的模块模式,我可以让全局处理程序正常工作,但是这个测试代码不起作用,我很难弄清楚为什么:

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 中的强制行为。但我已经服用了蓝色药丸,感觉自己离兔子洞太远了,无法爬出来。

4

1 回答 1

2

只需更换

var x = {};

var x = $("<div></div>");

Javascript 事件需要绑定到有效的 DOM 对象(不仅仅是 javascript 对象)。现在,不需要将 DOM 对象实际附加到任何地方。Javascript 的事件系统基于在可用和相关 DOM 对象的层次链中上下冒泡事件。简单{}的不合格。

于 2012-09-24T05:01:48.100 回答