我尝试覆盖JQuery的.show和.hide方法,以便在使用以下代码调用它们之前和之后启动触发器事件。
$(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]);
});
}
});
我有以下标记:
<input type='text' id='dataBox'/>
<input type='button' value='toggle' id='toggleButton' />
当我点击切换按钮时,'beforeHide'和'beforeShow'事件正在触发,而'afterShow'和'afterHide'则没有。谁能让我知道我做错了什么?
答案 0 :(得分:6)
检查demo fiddle。希望它有效
$。show / $ .hide - 覆盖功能:
(function($){
$.override ={'show': $.fn.show, 'hide': $.fn.hide};
$.each($.override,function(M,F){
var m=M.replace( /^\w/, function(r){ return r.toUpperCase(); });
$.fn[M] = function(speed, easing, callback) {
var args=[speed||0,easing||'',callback||function(){}];
if( $.isFunction(speed)){
args[2]=speed;
args[0]=0;
}
else if( $.isFunction(easing)){
args[2]=easing;
args[1]='';
}
if(!this.selector){
F.apply(this, arguments);
return this;
}
return this.each(function () {
var obj = $(this),
oldCallback = args[args.length-1],
newCallback = function () {
if ($.isFunction(oldCallback)){
oldCallback.apply(obj);
}
obj.trigger('after'+m);
};
obj.trigger('before'+m);
args[args.length-1]=newCallback;
//alert(args);
F.apply(obj,args);
});
}
});
})(jQuery);
<强>使用强>
jQuery(function($){
var $dataBox=$('#dataBox').bind('beforeHide afterHide beforeShow afterShow', function(e) {
alert(e.type);
});
$('#toggleButton').bind('click',function(){
$dataBox[$dataBox.is(':visible')?'hide':'show'](100,'swing',function(){ alert('end of animation');});
return false;
});
});
答案 1 :(得分:3)
我在您的代码中设置了一些断点,并且发现您永远不会调用newCallback
函数。多数民众赞成我认为,因为你在调用该函数时没有使用速度参数。
从jQuery原始函数的文档$.show可以看出,您可以使用$.show
,no
,one
或“三个参数”来调用two
.show(duration [,callback])
duration一个字符串或数字,用于确定动画运行的时间。
callbackA动画完成后调用的函数。
版本添加:1.4.3
.show([duration] [,easing] [,callback])
duration一个字符串或数字,用于确定动画运行的时间。
easing一个字符串,指示要用于转换的缓动函数。
callbackA动画完成后调用的函数。
所以你可能会或可能不会传递一堆不同的参数。所以我认为问题出在这一行
_oldHide.apply(obj, [speed, newCallback]);
在此特定情况下,speed
未定义。
您可以将$.fn.show
功能称为
$(..).show(undefined,callBack)
//or
$(..).show(undefined,undefined, callBack)
如果没有指定其他参数,回调将始终必须是第一个参数,在这种情况下,jQuery将使用它的动画默认400ms
速度/持续时间。你会看到一个fadeIn / fadeOut类型的效果。使其像使用此回调一样显示/隐藏
您必须致电_oldShow/_oldHide
_oldShow.apply(obj, [0,newCallback]);
//or
_oldHide.apply(obj, [0,newCallback]);
在快速搜索中,我在互联网上找到了一个代码,它似乎运行正常,并且可以对您传递给$.show
和$.hide
的所有参数进行特殊处理。检查以下小提琴,看看
答案 2 :(得分:3)
afterShow
和afterHide
事件未被触发如果显示/隐藏动画,jQuery将只调用代码中的回调函数(newCallback
)。如果没有参数传递给.show()
/ .hide()
(或speed
是undefined
),那么jQuery将直接显示/隐藏元素,以及回调函数不会被执行。
.show()
/ .hide()
不是最好的主意 jQuery在内部调用.show()
/ .hide()
(例如作为.fadeTo()
的一部分)并递归调用(在进行动画显示/隐藏时),因此将触发自定义事件当你可能没想到他们的时候。
恕我直言,最好将“股票”jQuery和自定义分开(作为插件),使用单独的方法名称/命名空间:
.eventedShow()
/ .eventedHide()
这会添加.eventedShow()
和.eventedHide()
(与.show()
/ .hide()
采用相同的参数)并且应该按照您的意愿执行操作:
(function( $ ) {
$.each( [ 'Show', 'Hide' ], function( i, method ) {
$.fn[ 'evented' + method ] = function( speed ) {
var originalMethod = method.toLowerCase(),
hasCallback = false,
args;
// animate
if ( speed || speed === 0 ) {
args = $.makeArray( arguments );
$.each( args, function( i, arg ) {
if ( $.isFunction( arg ) ) {
args[ i ] = function() {
arg.apply( this, arguments );
$( this ).trigger( 'after' + method );
};
hasCallback = true;
return false;
}
} );
if ( !hasCallback ) {
args.push( function() {
$( this ).trigger( 'after' + method );
} );
}
this.each( function() {
var el = $( this );
el.queue( function() {
$( this )
.trigger( 'before' + method )
.dequeue();
} );
$.fn[ originalMethod ].apply( el, args );
} );
// straight show/hide
} else {
this.trigger( 'before' + method );
$.fn[ originalMethod ].apply( this, arguments );
this.trigger( 'after' + method );
}
return this;
};
} );
})( jQuery );
您可以在此处尝试代码:http://jsfiddle.net/jefferyto/bv8D2/
您仍需要在现有代码中将show
/ hide
更改为eventedShow
/ eventedHide
,但这可以通过全局搜索完成 - 并且 - 取代