问题
I have a div of which collapse and expands using slideToggle and easing.
$('button').click(function () {
$('div').slideToggle('2000', "easeOutBounce");
});
I want it when it slide's Up to have a minimum height so that there always a small visible content of it.
So when it's slide down has height:(div height)
and on slideUp, height:10px;
Note that the div could have any amount of height so that's why I am not using animation.
回答1:
The best I could come up with is the following:
var toggleMinHeight = 30,
duration = 2000,
easing = 'swing';
$('.toggles').each(
function(){
$(this).attr('data-height',$(this).height());
}).click(
function(){
var curH = $(this).height();
if ($(this).is(':animated')){
return false;
}
else if (curH == $(this).attr('data-height')) {
$(this).animate(
{
'height' : toggleMinHeight
}, duration, easing);
}
else if (curH == toggleMinHeight){
$(this).animate(
{
'height' : $(this).attr('data-height')
}, duration, easing);
}
});
JS Fiddle demo.
This demo has some issues, however:
- No easing functionality beyond that specified by the basic jQuery library (giving access to 'swing' and 'linear'), this could be improved by including jQuery UI, however.
- It could almost certainly be made into a plug-in, to be somewhat less icky to look at.
- Requires a large, functional but not pretty,
if
/else if
statement. - Requires at least one pass of the
each()
to assign the 'default'/'natural' height of the div elements. - If the
div
s aren'tposition: absolute
they shrink down to the baseline of the in-line elements (as they'redisplay: inline-block
), this may not be a problem if they'refloat: left
(orfloat: right
, obviously).
Hopefully it's of use, but it's certainly not ideal in its current state.
Edited to post the plugin-ised version of the above (it retains all the same issues as before):
(function($) {
$.fn.slideTo = function(slideToMin, duration, easing) {
var slideToMin = slideToMin || 30,
duration = duration || 500,
easing = easing || 'linear';
$(this)
.attr('data-height', $(this).height())
.click(
function() {
var curH = $(this).height();
if ($(this).is(':animated')) {
return false;
}
else if (curH == $(this).attr('data-height')) {
$(this).animate({
'height': slideToMin
}, duration, easing);
}
else if (curH == slideToMin) {
$(this).animate({
'height': $(this).attr('data-height')
}, duration, easing);
}
});
return $(this);
};
})(jQuery);
$('.toggles').slideTo(50,1500,'swing');
JS Fiddle demo.
- slideToMin: this can be either a quoted string, such as '3em', '20px', or an unquoted number, such as
30
, and represents the height to which you want the element to slide to. If there are no units supplied then the height is, by default, considered to be in pixels. - duration: the number of milliseconds for which the animation lasts.
- easing:
a quoted string defining the type of easing to be used in the animation; without jQuery UI this is either 'linear' or 'swing'. With jQuery UI other options may be possible, but this is untested. If unspecified the animation defaults to 'linear.'Because using units in a quoted string causes the finalelse if
to return false (obviously, I suppose...sigh), please use only an unquoted numerical argument for this variable (or edit the plug in to properly deal with quoted strings with units...).
A larger issue that I hadn't realised until I posted this, is that the plugin version only allows one iteration of the animation. Which I'm confused about, though perhaps it's obvious to someone else?
Okay, it appears to be the evaluation of the height in the if
statement. Using 3em
caused the final else if
: curH == toggleMinHeight
to return false. Presumably due to the presence of the unit (em
) in that variable. The above guidance has been edited to reflect that the units should not be used.
References:
- animate().
- :animated selector.
- attr().
- click().
- each().
- height().
- is().
回答2:
Not really. When the slide method is called, it gets the style property
display: none;
However, you may be able to dynamically fix it by using the callback function
$('div').slideToggle('2000', "easeOutBounce", function() {
$('div')[0].style.height="//whatever//" //You could also use the min-height property
$('div')[0].style.display="inline";
);
What exactly is the problem with animation?
回答3:
I suggest that you play it tricky;
why dont you have a div above the sliding div that has the same width and color so that it is always displayed and appears as part of the sliding part
来源:https://stackoverflow.com/questions/8464899/is-it-possible-to-slidetoggle-a-div-with-easing-and-set-a-min-height