Animated add/remove list items test
Adding/removing list items with animation.
by Travis Almand
HTML
<button id="add">add item</button>
<ul id="list"></ul>
CSS
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
margin: 0;
padding: 0;
}
button {
border-radius: 50%;
cursor: pointer;
margin: 10px;
padding: 10px;
}
ul {
list-style: none;
margin: 0;
padding: 0;
position: relative;
}
li:not(#dummy) {
background-color: green;
height: 40px;
line-height: 40px;
margin: 10px;
padding: 0 10px;
}
.new-item {
animation: newItem 0.5s 0.5s forwards;
left: 0;
opacity: 0;
position: absolute;
top: -10px;
width: calc(100% - 20px);
}
.remove-item {
animation: removeItem 0.5s forwards;
left: 0;
position: absolute;
top: -10px;
width: calc(100% - 20px);
}
#dummy {
height: 40px;
line-height: 40px;
margin: 10px;
overflow: hidden;
}
#dummy.in {
animation: appearDummy 0.5s;
}
#dummy.out {
animation: goAwayDummy 0.5s 0.5s forwards;
}
@keyframes newItem {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes removeItem {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes appearDummy {
0% {
height: 0;
margin: 0 10px;
}
100% {
height: 40px;
margin: 10px 10px;
}
}
@keyframes goAwayDummy {
0% {
height: 40px;
margin: 10px 10px;
}
100% {
height: 0;
margin: 0 10px;
}
}
JavaScript
var $add = document.querySelector('#add');
var $list = document.querySelector('#list');
var $newItem;
var newItemString = '<li class="new-item">item</li>';
var $removeItem;
var $dummyItem;
var dummyItemString = '<li id="dummy"> </li>';
$add.addEventListener('click', addItem);
$list.addEventListener('click', removeItem);
function addItem() {
$add.disabled = true;
$list.insertAdjacentHTML('afterbegin', dummyItemString);
$list.insertAdjacentHTML('afterbegin', newItemString);
$newItem = document.querySelector('.new-item');
$dummyItem = document.querySelector('#dummy');
$dummyItem.classList.add('in');
$newItem.addEventListener('animationend', addItemDone, {once: true});
}
function removeItem(e) {
e.target.classList.add('remove-item');
e.target.insertAdjacentHTML('beforebegin', dummyItemString);
$removeItem = document.querySelector('.remove-item');
$dummyItem = document.querySelector('#dummy');
$dummyItem.classList.add('out');
$removeItem.addEventListener('animationend', removeItemDone, {once: true});
}
function addItemDone() {
$add.disabled = false;
$newItem.classList.remove('new-item');
$dummyItem.remove();
}
function removeItemDone() {
$removeItem.remove();
$dummyItem.addEventListener('animationend', function () {
$dummyItem.remove();
}, {once: true});
}