re:jQuery;将全局ajax事件绑定到非DOM对象

时间:2012-09-24 03:04:02

标签: javascript ajax jquery module-pattern

基本模块问题:如果我放弃我的模块模式,我可以让全局处理程序正常工作,但是这个测试代码不起作用,我很难找出原因:

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”通过两种模式绑定,不同的触发方法显示模式特异性......你将获得两次“手动”警报和一次“速记”警报。 / p>

现在,您还可以使用$.event.trigger("foo")触发全局事件(但是,不存在等效的全局triggerHandler)。 问题是如果你把这个代码添加到最后:

window.alert("now we trigger (globally)");
$.event.trigger("foo");

这个全局事件触发都没有运行处理程序。

但是,如果您将item替换为某种DOM类型元素(如上所述),则会处理本地 AND 全局事件,但需要注意的是“速记”处理程序现在不起作用*。所以看起来虽然本地处理适用于非DOM对象,但具体全局处理不起作用。

-m

*简写处理程序停止工作,因为简写模式 ONLY 适用于非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属性(尽管在检查控制台上的对象时它显示正确)?

注意:现在这一切都是为了知识 - 因为我只是在上面的bug链接中接受“修复”的建议,并将我所有的AJAX(和其他全局)事件附加到{{1因为它似乎是jQuery 1.9中的强制行为。 但是我已经服用了蓝色药丸,觉得我在兔子洞的距离太远,无法爬回来。

1 个答案:

答案 0 :(得分:2)

简单地替换

var x = {};

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

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