Javascript 如何将jQuery与自定义事件一起使用?

Javascript 如何将jQuery与自定义事件一起使用?,javascript,jquery,jquery-1.5,jquery-deferred,Javascript,Jquery,Jquery 1.5,Jquery Deferred,我有两个抽象过程(例如,在js对象中使用不暴露其内部的暴露模块模式进行管理),它们在完成时触发。我想在两个自定义事件都已触发时执行操作 var df1 = $.Deferred(), df2 = $.Deferred(); $('whatever').bind('customevent1', function() { // code code code df1.resolve(); }).bind('customevent2', function() { // code code c

我有两个抽象过程(例如,在js对象中使用不暴露其内部的暴露模块模式进行管理),它们在完成时触发。我想在两个自定义事件都已触发时执行操作

var df1 = $.Deferred(), df2 = $.Deferred();
$('whatever').bind('customevent1', function() {
  // code code code
  df1.resolve();
}).bind('customevent2', function() {
  // code code code
  df2.resolve();
});

var whenBoth = $.when(df1, df2);

whenBoth.then(function() {
  // code to run after both "customevent1"
  // and "customevent2" have fired
});
jQuery1.5中的新逻辑似乎是管理这一点的理想方法,除了when()方法接受返回promise()的延迟对象(或者普通的js对象,但是when()立即完成而不是等待,这对我来说是无用的)

理想情况下,我想做以下事情:

//execute when both customevent1 and customevent2 have been fired
$.when('customevent1 customevent2').done(function(){
  //do something
});

将这两种技术结合起来的最佳方法是什么?

您可以让“customevent1”和“customevent2”的事件处理程序在触发时都发出“延迟”实例的信号。然后可以使用“$.when()”将这两个事件合并为一个,只有在两个自定义事件都触发后,才可以在其中触发处理程序

var df1 = $.Deferred(), df2 = $.Deferred();
$('whatever').bind('customevent1', function() {
  // code code code
  df1.resolve();
}).bind('customevent2', function() {
  // code code code
  df2.resolve();
});

var whenBoth = $.when(df1, df2);

whenBoth.then(function() {
  // code to run after both "customevent1"
  // and "customevent2" have fired
});

老答案,为了完整起见

您可以创建自己的延迟对象来跟踪这两个条件,并在设置这两个条件时触发“resolve”:

function watchEvents() {
  var df = $.Deferred();

  var flags = {};
  $.each(Array.prototype.slice.call(arguments, 0), function() {
    flags[this] = false;
  });

  var realResolve = df.resolve.bind(df);
  df.resolve = function(eventName) {
    flags[eventName] = true;
    for (var ev in flags) if (flags[ev] === false) return;
    realResolve();
  };

  return df;
}
现在可以调用该函数:

var df = watchEvents("customevent1", "customevent2");
现在,这些事件的事件处理程序只需在捕获事件时调用“resolve”:

    df.resolve(event.type);
每个处理程序都报告自己的类型。只有当调用“watchEvents”时请求的所有事件类型都发生时,您在“df”上注册的处理程序函数才会真正被调用

我突然想到,您可以做的另一件事是编写jQuery插件,为元素初始化延迟对象,并将其存储在“.data()”属性中。然后,您可以编写更多的插件,事件处理程序可以使用这些插件来为自己发送信号,而其他插件可以为多事件序列注册处理程序。我想那会很酷,但我需要花些时间考虑一下。

我创建了一个小插件,它创建了一个新的jQuery.fn.when方法

语法是:

jQuery( "whatever" ).when( "event1 event2..." ).done( callback );
它在内部广泛使用jQuery.when(),并确保在解析之前已在集合中的所有元素上触发所有事件


实际插件代码如下:

( function( $ ) {

    $.fn.when = function( events ) {

        var deferred, $element, elemIndex, eventIndex;

        // Get the list of events
        events = events.split( /\s+/g );

        // We will store one deferred per event and per element
        var deferreds = [];

        // For each element
        for( elemIndex = 0; elemIndex < this.length; elemIndex++ ) {
            $element = $( this[ elemIndex ] );
            // For each event
            for ( eventIndex = 0; eventIndex < events.length; eventIndex++ ) {
                // Store a Deferred...
                deferreds.push(( deferred = $.Deferred() ));
                // ... that is resolved when the event is fired on this element
                $element.one( events[ eventIndex ], deferred.resolve );
            }
        }

        // Return a promise resolved once all events fired on all elements
        return $.when.apply( null, deferreds );
    };

} )( jQuery );
(函数($){
$.fn.when=函数(事件){
递延风险值,$element,elemIndex,eventIndex;
//获取事件列表
events=events.split(/\s+/g);
//我们将为每个事件和每个元素存储一个延迟
风险值递延=[];
//对于每个元素
for(elemIndex=0;elemIndex
上面的“df.reserve”是打字错误吗?我在jQuery延迟API文档中找不到reserve属性。如果你能提供一个链接,如果它存在的话,我将不胜感激。另外-有一个更好的方法可以做到这一点,但我正在尝试几种替代方法-我将很快更新。非常好的解决方案。如果存在大量节点或事件,那么使用“each”的多个内部循环可能会带来一些性能问题,但老实说,目前我还没有看到改进此解决方案的方法。谢谢你的回答。利用for循环并使用$.Deferred(fn)签名创建一个适当的闭包来解除绑定。+1太棒了!我将使用类似的方法异步加载自定义UI控件。在延迟开始发挥作用之前,管理多个级别的事件是令人讨厌的!