Programing

jQuery를 사용하여 요소를 자동 높이로 애니메이션

crosscheck 2020. 5. 28. 07:58
반응형

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의 크기를 알고 있습니다. 이 속성은 DOM 노드에로 저장됩니다 scrollHeight. 호출하여 jQuery Element에서 DOM Element를 가져와야 get(0)속성에 액세스 할 수 있습니다.

높이를 자동으로 설정하기 위해 콜백 함수를 추가하면 애니메이션이 완료된 후 응답 성이 향상됩니다 (신용 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 heres the code.

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"});});

선택기가 일치하지 않는 것 같습니다. 요소의 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 );
});

BORDER-BOX와 함께 작동하는 것이 있습니다 ...

여러분 안녕하세요. 다음은 동일한 작업을 수행하기 위해 작성한 jQuery 플러그인이지만로 box-sizing설정 했을 때 발생하는 높이 차이를 설명 합니다 border-box.

또한 y 축을 따라 요소를 축소하여 요소를 숨기는 "yShrinkOut"플러그인도 포함했습니다.


// -------------------------------------------------------------------
// 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 높이를 설정하려면이 매개 변수를 사용하십시오.
  • duration : 애니메이션의 길이입니다 ( 분명히 ).
  • 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>


이 스레드가 오래되었지만이 답변을 게시하고 있습니다. 나는 나를 위해 일할만한 대답을 얻을 수 없었다. 이것은 잘 작동하며 매우 간단합니다.

원하는 각 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);
    }
});

한 페이지에 여러 개의 더 많은 영역을 읽기 위해이 기능이 필요했습니다.

기술적으로 페이지의 모든 추가 읽기 범위의 높이는 고정되어 있습니다. 그리고 토글을 사용하여 자동 높이로 개별 확장 할 수 있기를 원했습니다. 첫 번째 클릭 : '텍스트 높이의 전체 높이로 확장', 두 번째 클릭 : '기본 높이 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특성 I는 요소의 실제 (동적) 높이를 저장하는데 사용.

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);
    });

});

First I've used a clickToggle function for my first and second click. The second function is more important: setAttr_height() All of the .read-more elements have their actual heights set on page load in the base-height attribute. After that the base height is set through the jquery css function.

With both of our attributes set we now can toggle between them in a smooth way. Only chang the data-base to your desired (fixed)height and switch the .read-more class for your own ID

You can all see it working in a fiddle FIDDLE

No jQuery UI needed


If all you are wanting is to show and hide say a div, then this code will let you use jQuery animate. You can have jQuery animate the majority of the height you wish or you can trick animate by animating to 0px. jQuery just needs a height set by jQuery to convert it to auto. So the .animate adds the style="" to the element that .css(height:auto) converts.

The cleanest way I have seen this work is to animate to around the height you expect, then let it set auto and it can look very seamless when done right. You can even animate past what you expect and it will snap back. Animating to 0px at a duration of 0 just simply drops the element height to its auto height. To the human eye, it looks animated anyway. Enjoy..

    jQuery("div").animate({
         height: "0px"/*or height of your choice*/
    }, {
         duration: 0,/*or speed of your choice*/
         queue: false, 
         specialEasing: {
             height: "easeInCirc"
        },
         complete: function() {
             jQuery(this).css({height:"auto"});
        }
    });

Sorry I know this is an old post, but I felt this would be relevant to users seeking this functionality still with jQuery who come across this post.


I put together something that does exactly what I was looking for and looks great. Using the scrollHeight of an element gets you the height of when it was loaded in the 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>

참고URL : https://stackoverflow.com/questions/5003220/animate-element-to-auto-height-with-jquery

반응형