Calculate the future height of a element

自闭症网瘾萝莉.ら 提交于 2020-01-06 08:26:32

问题


My intent is to animate using CSS3 the transition of height of a element when a child div get expanded.

<div id="container">
  <div id="content"> 
    <span>Small Conent</span>

    <div id="big">
      <p>
         This is way bigger content, will be visible after you have clicked the
         "Expand" button.
      </p>
      <p>It should animate up to the correct position.</p>
    </div>
  </div>

  <button id="expand">Expand</button>
</div>

I came up with this hack, using max-height. But there are a couple of problems:

  • The max-height must have a value
  • The animation will start and stop according to the max-height given value, so if you insert a crazy value like 2000px the animation will have a great delay.

To better illustrate the problem, I created a Fiddle: http://jsfiddle.net/egDsE/3/

The only way of having a precise animation, is to insert the correct value of max-height.

My intention is to calculate using JavaScript (and JavaScript only) what the height of the parent will be once the child is expanded. But of course, I will need to calculate it before the actual transition takes place.

Is this possible? Only pure JS please.


回答1:


Actually, you don't need to do all of the that cloning and stuff...just give the element height auto, check the size and set the height back to 0. It'll happen so fast the browser has no chance to repaint.

Now, this works like a charm, but the thing is that setting the height in Javascript immediately afterward will cause the transition to fail. I just throw a 100ms timeout around it and then it works fine.

Javascript:

document.getElementById('expand').addEventListener('click', function () {
    var el = document.getElementById('big');
    if (!el.className) {
        el.className = 'expanded';
        document.getElementById('expand').innerHTML = 'Retract';
        var elH = getHeight(el);
        window.setTimeout(function() {
            el.style.height = elH+'px';
        }, 100);
    } else {
        el.className = '';
        el.style.height = '0';
        document.getElementById('expand').innerHTML = 'Expand';
    }
});

function getHeight(el) {
    el.style.height = 'auto';
    elHeight = el.offsetHeight;
    el.style.height = '0';
    return elHeight;
}

CSS:

#container {
    border: 1px solid gray;
    padding: 20px;
}
#big {
    overflow: hidden;
    height: 0;
    transition: height 0.5s ease-in-out;
    -webkit-transition: height 0.5s ease-in-out;
    -moz-transition: height 0.5s ease-in-out;
    -o-transition: height 0.5s ease-in-out;
}

HTML: no changes to your markup

<div id="container">
    <div id="content"> <span>Small Conent</span>

        <div id="big">
            <p>This is way bigger content, will be visible after you have clicked the "Expand" button.</p>
            <p>It should animate up to the correct position.</p>
        </div>
    </div>
    <button id="expand">Expand</button>
</div>

DEMO




回答2:


I have updated the Fiddle with the solution proposed in the comments by Bartdude, optimizing it for performances as possible.

http://jsfiddle.net/egDsE/5/

var calculateHeight = function(e) {
    var outside = document.getElementById('outside');
    var clone = e.cloneNode(true);
    outside.appendChild(clone);
    var elHeight = outside.offsetHeight;
    outside.removeChild(clone);

    return elHeight;
}

The outside div have very basic css:

#outside {
    position: absolute;
    top: -1000;
    left: -1000;
}

I won't recommend this solution if image are involved, they would slow down the operation significantly.




回答3:


not to be that guy but I would use LESS if you don't want to be as intensive and get this functionality



来源:https://stackoverflow.com/questions/24634464/calculate-the-future-height-of-a-element

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!