繁体   English   中英

使用jQuery将元素动画化为自动高度

[英]Animate element to auto height with jQuery

我想将<div>200pxauto高度。 我似乎无法让它工作。 有谁知道怎么样?

这是代码:

$("div:first").click(function(){
  $("#first").animate({
    height: "auto"
  }, 1000 );
});
  1. 保存当前高度:

     var curHeight = $('#first').height(); 
  2. 暂时将高度切换为自动:

     $('#first').css('height', 'auto'); 
  3. 获得自动高度:

     var autoHeight = $('#first').height(); 
  4. 切换回curHeight并设置为autoHeight动画:

     $('#first').height(curHeight).animate({height: autoHeight}, 1000); 

和在一起:

var el = $('#first'),
    curHeight = el.height(),
    autoHeight = el.css('height', 'auto').height();
el.height(curHeight).animate({height: autoHeight}, 1000);

IMO这是最干净,最简单的解决方案:

$("#first").animate({height: $("#first").get(0).scrollHeight}, 1000 );

说明:DOM已经从其初始渲染中知道扩展div在设置为自动高度时将具有的大小。 此属性作为scrollHeight存储在DOM节点中。 我们只需要通过调用get(0)从jQuery元素中获取DOM元素,然后我们就可以访问该属性。

添加回调函数将高度设置为auto可以在动画完成后提供更高的响应能力(credit chris-williams ):

$('#first').animate({
    height: $('#first').get(0).scrollHeight
}, 1000, function(){
    $(this).height('auto');
});

这与Box9的答案基本相同,但是我将它包装在一个漂亮的jquery插件中 插件 采用与常规动画相同的参数 ,因为当你需要有更多的动画参数并厌倦了反复重复相同的代码时:

;(function($)
{
  $.fn.animateToAutoHeight = function(){
  var curHeight = this.css('height'),
      height = this.css('height','auto').height(),
      duration = 200,
      easing = 'swing',
      callback = $.noop,
      parameters = { height: height };
  this.css('height', curHeight);
  for (var i in arguments) {
    switch (typeof arguments[i]) {
      case 'object':
        parameters = arguments[i];
        parameters.height = height;
        break;
      case 'string':
        if (arguments[i] == 'slow' || arguments[i] == 'fast') duration = arguments[i];
        else easing = arguments[i];
        break;
      case 'number': duration = arguments[i]; break;
      case 'function': callback = arguments[i]; break;
    }
  }
  this.animate(parameters, duration, easing, function() {
    $(this).css('height', 'auto');
    callback.call(this, arguments);
  });
  return this;
  }
})(jQuery);

编辑:现在可链接和清洁

更好的解决方案不依赖于JS来设置元素的高度。 以下是将固定高度元素设置为完整(“自动”)高度的解决方案:

var $selector = $('div');
    $selector
        .data('oHeight',$selector.height())
        .css('height','auto')
        .data('nHeight',$selector.height())
        .height($selector.data('oHeight'))
        .animate({height: $selector.data('nHeight')},400);

https://gist.github.com/2023150

这是有效的,它比以前的解决方案更简单:

CSS:

#container{
  height:143px;  
}

.max{
  height: auto;
  min-height: 143px;
}

JS:

$(document).ready(function() {
    $("#container").click(function() {      
        if($(this).hasClass("max")) {
            $(this).removeClass("max");
        } else {
            $(this).addClass("max");
        }

    })
});

注意:此解决方案需要jQuery UI

var h = document.getElementById('First').scrollHeight;
$('#First').animate({ height : h+'px' },300);

您始终可以将#first的子元素包装起来,并将包装器的高度保存为变量。 这可能不是最漂亮或最有效的答案,但它可以解决问题。

这是一个小提琴 ,其中包括重置。

但为了你的目的,这里的肉和土豆:

$(function(){
//wrap everything inside #first
$('#first').children().wrapAll('<div class="wrapper"></div>');
//get the height of the wrapper 
var expandedHeight = $('.wrapper').height();
//get the height of first (set to 200px however you choose)
var collapsedHeight = $('#first').height();
//when you click the element of your choice (a button in my case) #first will animate to height auto
$('button').click(function(){
    $("#first").animate({
        height: expandedHeight            
    })
});
});​

使用slideDownslideUp

$("div:first").click(function(){ $("#first").slideDown(1000); });

我设法解决了它:D继承代码。

var divh = document.getElementById('first').offsetHeight;
$("#first").css('height', '100px');
$("div:first").click(function() {
  $("#first").animate({
    height: divh
  }, 1000);
});

基本上,自动高度仅在渲染元素后可用。 如果您设置了固定高度,或者未显示您的元素,则无法使用任何技巧来访问它。

幸运的是,你可能会使用一些技巧。

克隆元素,在视图外部显示它给它自动高度,你可以从克隆中取出它,稍后将它用作主元素。 我使用这个功能,似乎运作良好。

jQuery.fn.animateAuto = function(prop, speed, callback){
    var elem, height, width;

    return this.each(function(i, el){
        el = jQuery(el), elem =    el.clone().css({"height":"auto","width":"auto"}).appendTo("body");
        height = elem.css("height"),
        width = elem.css("width"),
        elem.remove();

        if(prop === "height")
            el.animate({"height":height}, speed, callback);
        else if(prop === "width")
            el.animate({"width":width}, speed, callback);  
        else if(prop === "both")
            el.animate({"width":width,"height":height}, speed, callback);
    });   
}

用法:

$(".animateHeight").bind("click", function(e){
    $(".test").animateAuto("height", 1000); 
});

$(".animateWidth").bind("click", function(e){
    $(".test").animateAuto("width", 1000);  
});

$(".animateBoth").bind("click", function(e){
    $(".test").animateAuto("both", 1000); 
});

你总是可以这样做:

jQuery.fn.animateAuto = function(prop, speed, callback){
var elem, height, width;
return this.each(function(i, el){
    el = jQuery(el), elem = el.clone().css({"height":"auto","width":"auto"}).appendTo("body");
    height = elem.css("height"),
    width = elem.css("width"),
    elem.remove();

    if(prop === "height")
        el.animate({"height":height}, speed, callback);
    else if(prop === "width")
        el.animate({"width":width}, speed, callback);  
    else if(prop === "both")
        el.animate({"width":width,"height":height}, speed, callback);
});  
}

这是一个小提琴: http//jsfiddle.net/Zuriel/faE9w/2/

您可以通过添加将高度设置为自动的回调来响应窗口大小更改,使Liquinaut的答案响应。

$("#first").animate({height: $("#first").get(0).scrollHeight}, 1000, function() {$("#first").css({height: "auto"});});

这是一个适用于BORDER-BOX的...

嗨,大家好。 这是我写的一个jQuery插件,但也考虑了将box-sizing设置为border-box时会出现的高度差异。

我还包括一个“yShrinkOut”插件,它通过沿y轴收缩来隐藏元素。


// -------------------------------------------------------------------
// Function to show an object by allowing it to grow to the given height value.
// -------------------------------------------------------------------
$.fn.yGrowIn = function (growTo, duration, whenComplete) {

    var f = whenComplete || function () { }, // default function is empty
        obj = this,
        h = growTo || 'calc', // default is to calculate height
        bbox = (obj.css('box-sizing') == 'border-box'), // check box-sizing
        d = duration || 200; // default duration is 200 ms

    obj.css('height', '0px').removeClass('hidden invisible');
    var padTop = 0 + parseInt(getComputedStyle(obj[0], null).paddingTop), // get the starting padding-top
        padBottom = 0 + parseInt(getComputedStyle(obj[0], null).paddingBottom), // get the starting padding-bottom
        padLeft = 0 + parseInt(getComputedStyle(obj[0], null).paddingLeft), // get the starting padding-left
        padRight = 0 + parseInt(getComputedStyle(obj[0], null).paddingRight); // get the starting padding-right
    obj.css('padding-top', '0px').css('padding-bottom', '0px'); // Set the padding to 0;

    // If no height was given, then calculate what the height should be.
    if(h=='calc'){ 
        var p = obj.css('position'); // get the starting object "position" style. 
        obj.css('opacity', '0'); // Set the opacity to 0 so the next actions aren't seen.
        var cssW = obj.css('width') || 'auto'; // get the CSS width if it exists.
        var w = parseInt(getComputedStyle(obj[0], null).width || 0) // calculate the computed inner-width with regard to box-sizing.
            + (!bbox ? parseInt((getComputedStyle(obj[0], null).borderRightWidth || 0)) : 0) // remove these values if using border-box.
            + (!bbox ? parseInt((getComputedStyle(obj[0], null).borderLeftWidth || 0)) : 0) // remove these values if using border-box.
            + (!bbox ? (padLeft + padRight) : 0); // remove these values if using border-box.
        obj.css('position', 'fixed'); // remove the object from the flow of the document.
        obj.css('width', w); // make sure the width remains the same. This prevents content from throwing off the height.
        obj.css('height', 'auto'); // set the height to auto for calculation.
        h = parseInt(0); // calculate the auto-height
        h += obj[0].clientHeight // calculate the computed height with regard to box-sizing.
            + (bbox ? parseInt((getComputedStyle(obj[0], null).borderTopWidth || 0)) : 0) // add these values if using border-box.
            + (bbox ? parseInt((getComputedStyle(obj[0], null).borderBottomWidth || 0)) : 0) // add these values if using border-box.
            + (bbox ? (padTop + padBottom) : 0); // add these values if using border-box.
        obj.css('height', '0px').css('position', p).css('opacity','1'); // reset the height, position, and opacity.
    };

    // animate the box. 
    //  Note: the actual duration of the animation will change depending on the box-sizing.
    //      e.g., the duration will be shorter when using padding and borders in box-sizing because
    //      the animation thread is growing (or shrinking) all three components simultaneously.
    //      This can be avoided by retrieving the calculated "duration per pixel" based on the box-sizing type,
    //      but it really isn't worth the effort.
    obj.animate({ 'height': h, 'padding-top': padTop, 'padding-bottom': padBottom }, d, 'linear', (f)());
};

// -------------------------------------------------------------------
// Function to hide an object by shrinking its height to zero.
// -------------------------------------------------------------------
$.fn.yShrinkOut = function (d,whenComplete) {
    var f = whenComplete || function () { },
        obj = this,
        padTop = 0 + parseInt(getComputedStyle(obj[0], null).paddingTop),
        padBottom = 0 + parseInt(getComputedStyle(obj[0], null).paddingBottom),
        begHeight = 0 + parseInt(obj.css('height'));

    obj.animate({ 'height': '0px', 'padding-top': 0, 'padding-bottom': 0 }, d, 'linear', function () {
            obj.addClass('hidden')
                .css('height', 0)
                .css('padding-top', padTop)
                .css('padding-bottom', padBottom);
            (f)();
        });
};

我使用的任何参数都可以省略或设置为null以接受默认值。 我使用的参数:

  • growTo:如果要覆盖所有计算并设置对象将增长的CSS高度,请使用此参数。
  • 持续时间:动画的持续时间( 显然 )。
  • whenComplete:动画完成时运行的函数。

切换幻灯片( Box9的答案扩大)

 $("#click-me").click(function() { var el = $('#first'), curHeight = el.height(), autoHeight = el.css('height', 'auto').height(), finHeight = $('#first').data('click') == 1 ? "20px" : autoHeight; $('#first').data('click', $(this).data('click') == 1 ? false : true); el.height(curHeight).animate({height: finHeight}); }); 
 #first {width: 100%;height: 20px;overflow:hidden;} 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="first"> <div id="click-me">Lorem ipsum dolor sit amet, consectetur adipiscing elit</div> Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, </div> 

您的选择器似乎不匹配。 你的元素的ID是'first',还是每个div中的第一个元素?

更安全的解决方案是使用'this':

// assuming the div you want to animate has an ID of first
$('#first').click(function() {
  $(this).animate({ height : 'auto' }, 1000);
});

试试这个,

var height;
$(document).ready(function(){
    $('#first').css('height','auto');
    height = $('#first').height();
    $('#first').css('height','200px');
})

 $("div:first").click(function(){
  $("#first").animate({
    height: height
  }, 1000 );
});

即使这个帖子已经老了,我也会发布这个答案。 我无法得到为我工作的公认答案。 这个很好用,非常简单。

我将每个div的高度加载到数据中

$('div').each(function(){
    $(this).data('height',$(this).css('height'));
    $(this).css('height','20px');
});

然后我在点击动画时使用它。

$('div').click(function(){
    $(this).css('height',$(this).data('height'));
});

我正在使用CSS转换,所以我不使用jQuery动画,但你可以做同样的动画。

您可以将其存储在数据属性中。

$('.colapsable').each(function(){
    $(this).attr('data-oheight',$(this).height());
    $(this).height(100);
});

$('.colapsable h2:first-child').click(function(){
    $(this).parent('.colapsable').animate({
            height: $(this).parent('.colapsible').data('oheight')
        },500);
    }
});

我需要这个功能,在一个页面上多个读取更多区域,将其实现为Wordpress短代码我遇到了同样的问题。

从技术上讲,页面上所有读取的跨度都有固定的高度。 我希望能够通过切换将它们分别扩展到自动高度。 首先点击:'展开到文字范围的全高',第二次点击:'折回到默认高度70px'

HTML

 <span class="read-more" data-base="70" data-height="null">
     /* Lots of text determining the height of this span */
 </span>
 <button data-target='read-more'>Read more</button>

CSS

span.read-more {
    position:relative;
    display:block;
    overflow:hidden;
}

所以上面这看起来非常简单我需要设置所需的固定高度的data-base属性。 我用来存储元素的实际(动态)高度的data-height属性。

jQuery部分

jQuery(document).ready(function($){

  $.fn.clickToggle = function(func1, func2) {
      var funcs = [func1, func2];
      this.data('toggleclicked', 0);
      this.click(function() {
          var data = $(this).data();
          var tc = data.toggleclicked;
          $.proxy(funcs[tc], this)();
          data.toggleclicked = (tc + 1) % 2;
      });
      return this;
  };

    function setAttr_height(key) {
        $(key).each(function(){
            var setNormalHeight = $(this).height();
            $(this).attr('data-height', setNormalHeight);
            $(this).css('height', $(this).attr('data-base') + 'px' );
        });
    }
    setAttr_height('.read-more');

    $('[data-target]').clickToggle(function(){
        $(this).prev().animate({height: $(this).prev().attr('data-height')}, 200);
    }, function(){
        $(this).prev().animate({height: $(this).prev().attr('data-base')}, 200);
    });

});

首先,我使用clickToggle功能进行第一次和第二次点击。 第二个函数更重要: setAttr_height()所有.read-more元素都在base-height属性中的页面加载上设置了它们的实际高度。 之后,通过jquery css函数设置基本高度。

通过设置我们的两个属性,我们现在可以平滑地在它们之间切换。 只将data-base更改为您想要的(固定)高度,并为您自己的ID切换.read-more类

你们都可以看到它在一个小提琴FIDDLE中工作

不需要jQuery UI

我把一些完全符合我要求的东西放在一起,看起来很棒。 使用元素的scrollHeight可以获得在DOM中加载它的高度。

  var clickers = document.querySelectorAll('.clicker'); clickers.forEach(clicker => { clicker.addEventListener('click', function (e) { var node = e.target.parentNode.childNodes[5]; if (node.style.height == "0px" || node.style.height == "") { $(node).animate({ height: node.scrollHeight }); } else { $(node).animate({ height: 0 }); } }); }); 
 .answer{ font-size:15px; color:blue; height:0px; overflow:hidden; } 
  <div class="row" style="padding-top:20px;"> <div class="row" style="border-color:black;border-style:solid;border-radius:4px;border-width:4px;"> <h1>This is an animation tester?</h1> <span class="clicker">click me</span> <p class="answer"> I will be using this to display FAQ's on a website and figure you would like this. The javascript will allow this to work on all of the FAQ divs made by my razor code. the Scrollheight is the height of the answer element on the DOM load. Happy Coding :) Lorem ipsum dolor sit amet, mea an quis vidit autem. No mea vide inani efficiantur, mollis admodum accusata id has, eam dolore nemore eu. Mutat partiendo ea usu, pri duis vulputate eu. Vis mazim noluisse oportere id. Cum porro labore in, est accumsan euripidis scripserit ei. Albucius scaevola elaboraret usu eu. Ad sed vivendo persecuti, harum movet instructior eam ei. </p> </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM