I have built a kind of password generator that should display a new password whenever the countdown expires. Unfortunately, I have only managed to figure out how to run my code once. The countdown consists of a simple CSS transition, which I would like to keep, because it is much smoother than my other attempts, wherein i tried to repeatedly update the width using JavaScript.
var dictionary = {
"adverbs": [
"always",
"usually",
"probably"
],
"adjectives": [
"useful",
"popular",
"accurate"
],
"nouns": [
"computer",
"software",
"terminal"
]
};
function capitalizeFirst(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
function randomIndex(object) {
return object[Math.floor(Math.random() * object.length)];
}
function generatePassword() {
var category = ["adverbs", "adjectives", "nouns"];
var password = [];
for (i = 0; i < category.length; i++) {
password.push(capitalizeFirst(randomIndex(dictionary[category[i]])));
}
password.push(Math.floor(Math.random() * 8999) + 1000);
return password.join("");
}
function updatePassword() {
document.getElementById("countdown-fill").style.width = 100 + '%';
document.getElementById("text-field").value = generatePassword();
document.getElementById("countdown-fill").style.width = 0 + '%';
}
setInterval(updatePassword, 5000);
@import url('https://fonts.googleapis.com/css?family=Nunito&display=swap');
body {
margin: 0;
width: 100%;
height: 100%;
background-color: #f8f8f8;
}
.container {
max-width: 400px;
margin: 0 auto;
}
#text-field {
font-size: 15px;
font-weight: 400;
font-family: 'Nunito', sans-serif;
margin-top: 100px;
margin-bottom: 10px;
width: 100%;
height: 30px;
padding: 10px;
box-sizing: border-box;
border: 1px solid #e5e5e5;
background-color: #ffffff;
}
#countdown-background {
width: 100%;
height: 10px;
box-sizing: border-box;
border: 1px solid #e5e5e5;
background-color: #ffffff;
}
#countdown-fill {
width: 100%;
height: 100%;
transition: width 5s;
transition-timing-function: linear;
background-color: #1e87f0;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Password Generator</title>
</head>
<body>
<div class="container">
<input id="text-field" type="text" spellcheck="false">
<div id="countdown-background">
<div id="countdown-fill"></div>
</div>
</div>
</body>
</html>
Currently, I have two apparent issues with my code:
- The transition becomes delayed due to
setInterval. This is not the case if I simply callupdatePasswordon its own. - The CSS transition only animates once. I would like to reset the animation every time i call
updatePassword.
I came across a few jQuery solutions for my problem, but I am not very interested in those, as I want to rely on standard JavaScript as much as possible. However, I am okay with alternative CSS tools like keyframes, which seem to work well:
#countdown-fill {
width: 100%;
height: 100%;
animation: refresh 5s infinite;
background-color: #1e87f0;
}
@keyframes refresh {
from {
width: 100%;
}
to {
width: 0;
}
}
Although, I do worry about synchronization issues as the animation is not coupled with updatePassword in any way.
Question: Is there a way to have updatePassword reset the animation each time I call the function, and remove the initial delay?