最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use CSS transition for existing list items to make room for new ones? - Stack Overflow

programmeradmin1浏览0评论

Suppose I have the following HTML:

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>AlwaysAtTheEnd</li>
</ul>

After list item 3, I will be inserting a list item 4 using javascript. After that happens, the HTML will look like this:

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>AlwaysAtTheEnd</li>
</ul>

However, I want the "AlwaysAtTheEnd" item to smoothly slide down to make room for the new item rather than instantly pop down to make space.

I tried simply adding the following CSS, but it doesn't seem to affect anything:

li {
    -webkit-transition: all 1s ease-in-out;
    -moz-transition: all 1s ease-in-out;
    -o-transition: all 1s ease-in-out;
    transition: all 1s ease-in-out;
}

Fiddle here: /

EDIT: Fixed fiddle: /

Suppose I have the following HTML:

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>AlwaysAtTheEnd</li>
</ul>

After list item 3, I will be inserting a list item 4 using javascript. After that happens, the HTML will look like this:

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>AlwaysAtTheEnd</li>
</ul>

However, I want the "AlwaysAtTheEnd" item to smoothly slide down to make room for the new item rather than instantly pop down to make space.

I tried simply adding the following CSS, but it doesn't seem to affect anything:

li {
    -webkit-transition: all 1s ease-in-out;
    -moz-transition: all 1s ease-in-out;
    -o-transition: all 1s ease-in-out;
    transition: all 1s ease-in-out;
}

Fiddle here: http://fiddle.jshell/pcsj2mgb/

EDIT: Fixed fiddle: http://fiddle.jshell/pcsj2mgb/1/

Share Improve this question edited Feb 13, 2015 at 12:03 adrianmcli asked Feb 13, 2015 at 11:10 adrianmcliadrianmcli 1,9963 gold badges23 silver badges49 bronze badges 3
  • The javascript you have in the fiddle is indeed wrong. You're appending a child node to the second last item. It should be as hitesh below did: appending to the parentNode of the second last item. Altough it could just be lastItem.parentNode.insertBefore(newItem, lastItem), skipping the use of nextSibling if you'd get the last item instead of the second last. – Sevanteri Commented Feb 13, 2015 at 11:45
  • @Sevanteri Okay, I've made the change here: fiddle.jshell/pcsj2mgb/1 but the animation still doesn't work. – adrianmcli Commented Feb 13, 2015 at 12:03
  • 2 I don't understand why this question is downvoted – Kun Commented Nov 27, 2017 at 18:55
Add a ment  | 

3 Answers 3

Reset to default 7

Can be done with CSS, though you are going to need to define the final height of the li elements so you can animate to that height.

And of course, you need to add the newItem class to the element you're appending, so the CSS affects it.

Update: No need to define a final height! Let's' just animate the max-height. Updated the snippet.

add = function() {
  listItems = document.getElementsByTagName('li');
  var lastItem = listItems[listItems.length - 1]
  var newItem = document.createElement('li');
  newItem.innerHTML = "4";

  newItem.classList.add("newItem");

  lastItem.parentNode.insertBefore(newItem, lastItem);
}
.newItem {
  max-height: 0;
  opacity: 0;
  animation: grow 1s ease-in-out forwards;
  -webkit-animation: grow 1s ease-in-out forwards;
}
@-webkit-keyframes grow {
  to {
    max-height: 20px;
    opacity: 1;
  }
}
@keyframes grow {
  to {
    max-height: 20px;
    opacity: 1;
  }
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>AlwaysAtTheEnd</li>
</ul>
<button onClick="add()">Add</button>

I have change in your javascript code :

add = function(){
    var listItems = document.getElementsByTagName('li');
    var secondLastItem = listItems[listItems.length - 2];
    var newItem = document.createElement('li');
    newItem.innerText = 4;

    // some pre defined css to new item
    newItem.style.height = '0px';
    newItem.style['opacity'] = '0';

    // This is change : because you are appending li into second last li, not in ul : so this function will insert li after last second item 
    secondLastItem.parentNode.insertBefore(newItem, secondLastItem.nextSibling);

    setTimeout(function(){
        // after append new item will get some css changes
        newItem.style.height = '18px';
        newItem.style['opacity'] = '1';
    },10)

}

you can see my fiddle link of this example : http://fiddle.jshell/13gg7kwf/

Adding the CSS values via Javascript is a bit of a dirty hack.

I have found a way to achieve this by using a CSS only solution( thanks to : http://christianheilmann./2013/09/19/quicky-fading-in-a-newly-created-element-using-css/).

Instead of using Transition you should use Animation.

You create a CSS class, and add it via JS, that triggers the animation right after the element is added to the DOM :

li.fade {
    -webkit-animation: fade 5s;
    animation: fade 5s;
    opacity: 1;
}
/* -fail- */
@-webkit-keyframes fade {
from {opacity: 0}
to {opacity: 1}
}@keyframes fade {
from {opacity: 0}
to {opacity: 1}
}

Complete solution : http://jsfiddle/8wdk63ce/

发布评论

评论列表(0)

  1. 暂无评论