Попытка запуска до и после событий вокруг jQuery show()

Я пытаюсь получить часть нашего JavaScript-скрипта после того, как какой-то сторонний код отобразит модальный диалог. Я видел довольно опрятную идею захвата функции show jQuery, но, к сожалению, она не работает. Я предполагаю, что эта идея использовалась для работы над старой версией jQuery еще в 2009 году, но не в последней версии. Вот jsFiddle с реализацией и образцом:

http://jsfiddle.net/mkmurray/drv5w/2/

Как вы можете видеть, запустив образец, он будет предупреждать о событии "beforeShow", но не "событие afterShow", и с некоторой отладкой я вижу, что он не вызывает функцию "newCallback" целиком.

Благодарим вас за любую помощь, которую вы можете предоставить.

Ответ 1

Похоже, я смог работать через решение. Это связано с несколькими факторами, которые не соответствуют оригиналу:

  • Начиная с оригинальной записи кода, который я видел, jQuery добавил еще один необязательный параметр с именем easing. Это действительно испортило то, как я делегировал исходный метод show в jQuery, вызывая _oldShow.apply(...).
  • После того, как я исправил это, я обнаружил, что иногда метод show вызывает серию других методов, которые иногда рекурсивно вызывают show снова. Мне нужен был способ, чтобы моя реализация не перехватывала эти рекурсивные вызовы; Я обнаружил, что могу положиться, если есть свойство selector или нет.

Рабочую реализацию можно найти здесь на этом jsFiddle:

http://jsfiddle.net/mkmurray/drv5w/27/

Эта реализация сильно зависит от jQuery, но не меняет сигнатуру метода show. Поэтому вам в значительной степени нужно решить, хотите ли вы изменить свои сторонние плагины jQuery, а не делать это. В любом случае, если вы хотите получить последнюю версию стороннего плагина или последнего jQuery, некоторые новые изменения могут нарушить вашу реализацию. Таким образом, это решение не обязательно лучше или хуже, чем модифицировать ваши сторонние плагины.

Ответ 2

Я нашел другое решение для этого здесь, с небольшим изменением.

(function($){
    $.each(['show','hide'],function(i,ev){
        var el = $.fn[ev];              
        $.fn[ev] = function(){
            this.trigger(ev);
            return el.apply(this,arguments);
        };
    });                  
})(jQuery);

Он не предлагает события до и после других примеров, но это, безусловно, можно было бы продолжить. Он работает для меня до сих пор и надеется, что он продолжит это делать - это хороший небольшой подход, который можно легко расширить до других функций jQuery, включая различные альтернативы для показа.

** Обратите внимание, что это также вызывает событие для "скрыть".

Ответ 3

Я ничего не тестировал, но делился несколькими вещами, которые я знаю.

  • show имеет необязательный второй параметр - ослабление. jQuery автоматически определяет это, но для идеального решения вы должны это учитывать.

    _oldShow.apply(obj, [speed, null, newCallback]); 
    
  • Обратный вызов имеет смысл только тогда, когда есть задержка, что означает значение для speed. Я надеюсь, что ваше событие afterShow будет запущено, если есть задержка. Если нет задержки, вы можете вызвать ее после вызова _oldShow, как этот

    _oldShow.apply(obj, [speed, null, newCallback]); 
    if(!speed){
      obj.trigger('afterShow');
    }
    

EDIT:

Я устал от нескольких вещей и frpm, что я узнал, я предлагаю вам создать новую функцию show вместо переопределения.

jQuery.fn.extend({

    show2:function( speed, easing, callback ) {
        this.trigger('beforeShow');
        this.show(speed, easing, function(){
            $(this).trigger('afterShow');
            if ($.isFunction(callback)) {
                callback.apply(this);
            }
        });
        if(!speed){
            this.trigger('afterShow');            
        }          
    }


});

demo: http://jsfiddle.net/9F8ea/2/