【问题标题】:How to smoothly add dynamically created element to the DOM using CSS3 only?如何仅使用 CSS3 将动态创建的元素平滑地添加到 DOM?
【发布时间】:2018-06-10 05:35:21
【问题描述】:

我的需求很简单,但我找不到合适的解决方案。

我创建元素并将它们作为项目列表添加到 DOM,每个新元素都添加在旧元素之前。我希望“顺利”添加新元素。每个元素的height 是动态的,因此必须是 CSS 规则。

我认为我必须使用 CSS animationskeyframes,从我读到的内容我不能使用 transitions,因为有时 it is not rendered by the browser。我不想使用 Javascript,所以我更喜欢避免使用 setTimeout()jQuery 的解决方案。我确信这可以使用现代 CSS 正确完成,但我仍然需要找到正确的方法。

我有一个解决方案的开始(见下文),在 CSS 中仍然有 max-height: 1000px 硬编码,我想避免这种情况,但我不知道该怎么做,因为将其替换为 autounset 会破坏动画(请参阅帖子末尾的 GIF)。

你将如何实现一个优雅的过渡来像这样向 DOM 添加新元素(不一定使用我提供的代码)?


Try the code on JSFiddle

    function addElement() {
        let dynamicHeight = Math.ceil(Math.random() * 30) + 100;
        let newElem = `<div class='elem' style='height: ${dynamicHeight}px'></div>`;
        let elements = document.getElementById("elements");
        elements.insertAdjacentHTML("afterbegin", newElem);
    }

    let button = document.getElementById("button")
    button.addEventListener("click", addElement);
    .elem {
      background-color: blue;
      margin: 5px;
      animation-duration:0.5s;
      animation-name: slidein;
    }
    
    
    @keyframes slidein {
      from {
        max-height: 0px;
        transform: scale(0);
        opacity: 0;
      }
    
      to {
        max-height: 1000px;
        transform: scale(1);
        opacity: 1;
      }
    }
    <button id="button">Add element</button>
    <div id="elements"></div>

使用硬编码的最大高度(看起来不错):

未设置最大高度(看起来很笨拙):

【问题讨论】:

  • 你试过使用 height: auto; ?
  • @ManuelBlanco 是的,我尝试过使用autounset100%,但对所有人来说都是“笨拙”。
  • @ibrahimmahrir “减少第二个动画的时间”是什么意思?我怎样才能做到这一点? “笨拙”的效果来自于旧元素“跳下”而不是平稳地移动到底部。
  • @Delgan 啊!我懂了。那么你要么使用max-height 或javascript,否则这是不可能的:你不能动画或从数字到非数字值的转换,反之亦然。
  • 我一直觉得使用max-height 滑动元素可能被高估了,因为它只会达到计算的高度。如果滑动是线性的,那么会有突然性,但缓动可以消除高估 max-height 的抖动可能(未测试)

标签: javascript css css-transitions css-animations


【解决方案1】:

由于您定义的是固定高度,因此解决方案是将高度从 0px 设置为固定值。这里的诀窍是依靠 CSS 变量来根据元素的高度生成动态动画:

function addElement() {
  let dynamicHeight = Math.ceil(Math.random() * 100) + 40;
  let newElem = `<div class='elem' style='--h: ${dynamicHeight}px'></div>`;
  let elements = document.getElementById("elements");
  elements.insertAdjacentHTML("afterbegin", newElem);
}

let button = document.getElementById("button")
button.addEventListener("click", addElement);
.elem {
  background-color: blue;
  margin: 5px;
  animation: slidein 0.5s forwards;
}

@keyframes slidein {
  from {
    height: 0px;
    transform: scale(0);
    opacity: 0;
  }
  to {
    height:var(--h); /*This will change for each element */
    transform: scale(1);
    opacity: 1;
  }
}
<button id="button">Add element</button>
<div id="elements"></div>

【讨论】:

  • 我不知道var(),谢谢!不幸的是,我真正的用例是没有固定高度的元素,这些只是具有可变长度内容的“块”元素。
  • @Delgan,好吧,让我想想另一种方式;)
  • 感谢您的帮助!顺便说一句,如果你设法进行任何“平滑”过渡,我可能会接受,即使没有规模转换或其他什么。这有点模糊,但只要添加新元素看起来“不错”,旧元素“滑下来”,我就会很高兴。 :)
猜你喜欢
  • 2018-01-21
  • 1970-01-01
  • 2019-05-24
  • 2017-11-08
  • 1970-01-01
  • 2016-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多