Is it possible to slideToggle a div with Easing and set a min-height?

后端 未结 3 1893
天命终不由人
天命终不由人 2021-01-13 17:44

I have a div of which collapse and expands using slideToggle and easing.

$(\'button\').click(function () {
    $(\'div\').slideToggle(\'2000\', \"easeOutBoun         


        
3条回答
  •  不知归路
    2021-01-13 18:01

    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 divs aren't position: absolute they shrink down to the baseline of the in-line elements (as they're display: inline-block), this may not be a problem if they're float: left (or float: 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.

    1. 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.
    2. duration: the number of milliseconds for which the animation lasts.
    3. 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 final else 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().

提交回复
热议问题