Why does CSS animation through javascript only happen once
Solution 1:
You need to remove the animation, then set it back to reset it:
let navChildren = [...document.getElementById('nav-container').children]
navChildren.forEach(x => {
x.addEventListener('click', () => {
})
x.addEventListener('mouseout', () => {
x.style.animation = "none";
setTimeout(function() {
x.style.animation = 'hoverOut 1s forwards'
}, 0)
})
})
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
li {
float: left;
}
li a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
li a:hover {
animation: hoverIn 0.5s forwards;
}
@keyframes hoverIn {
0% {
background-color: #333;
}
100% {
background-color: #111;
}
}
@keyframes hoverOut {
0% {
background-color: white;
}
100% {
background-color: #333;
}
}
.active {
background-color: #222;
}
<html>
<body>
<ul id='nav-container'>
<li><a href="#home">Home</a></li>
<li><a href="#news">News</a></li>
<li><a href="#contact">Contact</a></li>
<li><a href="#about">About</a></li>
</ul>
</body>
</html>
Although an easier way is just to use CSS transitions, no JavaScript required:
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
li {
float: left;
}
li a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
transition: 0.5s;
}
li a:hover {
background-color: white;
}
@keyframes hoverOut {
0% {
background-color: white;
}
100% {
background-color: #333;
}
}
.active {
background-color: #222;
}
<html>
<body>
<ul id='nav-container'>
<li><a href="#home">Home</a></li>
<li><a href="#news">News</a></li>
<li><a href="#contact">Contact</a></li>
<li><a href="#about">About</a></li>
</ul>
</body>
</html>
Solution 2:
Add the animationend
event listener to refresh the animation.
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations#using_animation_events
let navChildren = [...document.getElementById('nav-container').children]
navChildren.forEach(x => {
x.addEventListener("animationend",()=>x.style.animation = "none");
x.addEventListener('mouseout',()=>x.style.animation = 'hoverOut 1s forwards');
})
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
li {
float: left;
}
li a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
li a:hover {
animation: hoverIn 0.5s forwards;
}
@keyframes hoverIn {
0% { background-color: #333; }
100% { background-color: #111; }
}
@keyframes hoverOut {
0% { background-color: #111; }
100% { background-color: #333; }
}
.active { background-color: #222; }
<html>
<body>
<ul id = 'nav-container'>
<li><a href="#home">Home</a></li>
<li><a href="#news">News</a></li>
<li><a href="#contact">Contact</a></li>
<li><a href="#about">About</a></li>
</ul>
</body>
</html>