Подтвердить что ты не робот

Как использовать jQuery Отложенные с пользовательскими событиями?

У меня есть два абстрактных процесса (например, управляемые внутри объектов js с использованием шаблона раскрывающего модуля, которые не выставляют их внутренности), которые запускают настраиваемые события, когда они завершаются. Я хочу выполнить действие, когда запускаются оба пользовательских события.

Новая логика Deferred в jQuery 1.5 кажется, что это был бы идеальный способ справиться с этим, за исключением того, что метод when() принимает объекты с отсрочкой, которые возвращают обещание() (или обычные объекты js, но затем, когда() завершает немедленно, а не ждет, что бесполезно для меня).

В идеале я хотел бы сделать что-то вроде:

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

Каким будет лучший способ выйти замуж за эти два метода?

4b9b3361

Ответ 1

http://jsfiddle.net/ch47n/

Я создал небольшой плагин, который создает новый метод 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 );

Ответ 2

У вас могут быть обработчики событий для "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
});

Старый ответ, здесь для полноты

Вы можете создать свой собственный объект "Отложенный", который отслеживает два условия и "разрешает" огонь, когда оба установлены:

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");

И теперь ваши обработчики событий для этих событий просто должны вызвать "разрешить" эту вещь, когда они поймают события:

    df.resolve(event.type);

Каждый обработчик сообщает о своем собственном типе. Только когда все типы событий, запрошенные при вызове "watchEvents", произойдут, функции обработчика, которые вы регистрируете на "df", действительно вызываются.

Мне кажется, что еще одна вещь, которую вы могли бы сделать, - написать плагин jQuery, который инициализирует объект "Отложенные" для элементов и сохраняет его в свойстве ".data()". Затем вы могли бы написать еще несколько плагинов, которые могут использоваться обработчиками событий для сигнализации самих себя и других плагинов для регистрации обработчиков для последовательностей с несколькими событиями. Я думаю, это было бы круто, но мне нужно потратить некоторое время на размышления об этом.