I am tryign to override the JQuery's .show and .hide methods to launch trigger events before and after they are called with the following code.
$(document).ready(function () {
$('#dataBox').bind('afterShow', function () {
alert('afterShow');
});
$('#dataBox').bind('afterHide', function () {
alert('afterHide');
});
$('#dataBox').bind('beforeShow', function () {
alert('beforeShow');
});
$('#dataBox').bind('beforeHide', function () {
alert('beforeHide');
});
$('#toggleButton').click(function(){
if($('#dataBox').is(':visible')) {
$('#dataBox').hide ();
} else {
$('#dataBox').show();
}
});
});
jQuery(function ($) {
var _oldShow = $.fn.show;
//Override jquery's 'show()' method to include two triggered events before and after
$.fn.show = function (speed, oldCallback) {
return $(this).each(function () {
var obj = $(this),
newCallback = function () {
if ($.isFunction(oldCallback)) {
oldCallback.apply(obj);
}
obj.trigger('afterShow');
};
obj.trigger('beforeShow');
_oldShow.apply(obj, [speed, newCallback]);
});
}
});
jQuery(function ($) {
var _oldHide = $.fn.hide;
//Override jquery's 'hide()' method to include two triggered events before and after
$.fn.hide = function (speed, oldCallback) {
return $(this).each(function () {
var obj = $(this),
newCallback = function () {
if ($.isFunction(oldCallback)) {
oldCallback.apply(obj);
}
obj.trigger('afterHide');
};
obj.trigger('beforeHide');
_oldHide.apply(obj, [speed, newCallback]);
});
}
});
I have the following Markup:
<input type='text' id='dataBox'/>
<input type='button' value='toggle' id='toggleButton' />
When I click the toggle button the 'beforeHide' and 'beforeShow' events are triggering while the 'afterShow' and 'afterHide' aren't. Can anyone clue me in as to what I am doing wrong?
Why the
afterShow
andafterHide
events are not being triggeredjQuery will only call the callback function (
newCallback
in your code) if the show / hide is animated. If no parameters are passed to.show()
/.hide()
(or ifspeed
isundefined
), then jQuery will show / hide the element(s) directly, and the callback function will not be executed.Why overriding
.show()
/.hide()
isn't the best ideajQuery calls
.show()
/.hide()
internally (e.g. as part of.fadeTo()
) and recursively (when doing an animated show / hide), so your custom events will be triggered when you may not be expecting them to.IMHO it's best to keep "stock" jQuery and customizations separate (as plugins), with separate method names / namespaces:
.eventedShow()
/.eventedHide()
This adds
.eventedShow()
and.eventedHide()
(which takes the same arguments as.show()
/.hide()
) and should do what you want:You can try the code here: http://jsfiddle.net/jefferyto/bv8D2/
You'd still need to change
show
/hide
toeventedShow
/eventedHide
in your existing code, but this can be done with a global search-and-replace.I set some breakpoints in your code and saw that you
newCallback
function is never being called. Thats I think because you are not using the speed param when you are calling that function. As you can see from jQuery's original function's doc $.show, you can call$.show
withno
,one
,two
or `three parametersSo you you may or may not pass a bunch of different parameters. So I think the problem is in this line
Where in this specific case
speed
is undefined.And you can call
$.fn.show
function likeThe callback will always have to be the first argument if no other argument is specified and in that case jQuery will use it's default
400ms
speed/duration for the animation. And you will see a fadeIn/fadeOut type of effect. To make it behave like show/hide with this callbackYou have to call
_oldShow/_oldHide
likeIn a quick Search I found a a code in the internet which seems to work fine and have special handling for all arguments you can pass to
$.show
and$.hide
. Check the following fiddle to have a look at thatWorking Fiddle
plz check the demo fiddle . hope it works
$.show / $.hide - override function:
usage