Attempting to trigger before & after events around jQuery show()

后端 未结 3 1821
攒了一身酷
攒了一身酷 2021-02-15 02:15

I\'m trying to get a piece of our JavaScript run after some 3rd party code makes a modal dialog appear. I saw a pretty neat idea of hijacking the jQuery show function, but unfor

相关标签:
3条回答
  • 2021-02-15 02:54

    Looks like I was able to work through a solution. It involved a few factors going wrong with the original:

    1. Since the original writing of the code I saw, jQuery added another optional parameter named easing. This really messed with how I was delegating to the original show method in jQuery by calling _oldShow.apply(...).
    2. After I fixed that, I found that sometimes the show method calls a series of other methods that sometimes recursively call show again. I needed a way to not have my implementation intercept those recursive calls; I found that I could rely on if there was a selector property or not.

    A working implementation can be found here at this jsFiddle:

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

    This implementation is pretty dependent on jQuery not changing the method signature of the show method though. So you pretty much have to decide if you want to modify your 3rd party jQuery plugins instead of doing this. Either way, if you want to get latest of the 3rd party plugin or the latest jQuery, some new change could break your implementation. So this solution is not necessarily better or worse than modifying your third party plugins.

    0 讨论(0)
  • 2021-02-15 03:01

    I haven't tested anything, but sharing a few things I know

    1. show has an optional second parameter - easing. jQuery automatically detects this, but for a perfect a solution you have to consider this.

      _oldShow.apply(obj, [speed, null, newCallback]); 
      
    2. A callback makes sense only when there is a delay, that means value for speed. I hope your afterShow event will be triggered if there is a delay. If there is no delay you can trigger it after invoking _oldShow, like this

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

    EDIT:

    I tired a few things and frpm what I learned I would suggest you to create a new show function instead of overriding.

    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/

    0 讨论(0)
  • 2021-02-15 03:01

    I found another solution to this over here, with a slight tweak of my own.

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

    It doesn't offer the before/after events of other examples but it could certainly be elaborated on. It's working for me so far and hope it continues to do so--it's a nice little approach that can easily be expanded to other jQuery functions, including the various alternatives to show.

    ** Note this also fires an event for "hide".

    0 讨论(0)
提交回复
热议问题