javascript - 使用标准 JavaScript 结束后,如何重新启动 CSS 过渡?
问题描述
我已经构建了一种密码生成器,它应该在倒计时到期时显示一个新密码。不幸的是,我只设法弄清楚如何运行我的代码一次。倒计时由一个简单的 CSS 过渡组成,我想保留它,因为它比我的其他尝试平滑得多,其中我尝试使用 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>
目前,我的代码有两个明显的问题:
- 由于
setInterval
. 如果我只是updatePassword
自己调用,情况并非如此。 - CSS 过渡只动画一次。我想在每次打电话时重置动画
updatePassword
。
我遇到了一些 jQuery 解决方案来解决我的问题,但我对这些不是很感兴趣,因为我想尽可能地依赖标准 JavaScript。但是,我可以使用关键帧等替代 CSS 工具,它们似乎运行良好:
#countdown-fill {
width: 100%;
height: 100%;
animation: refresh 5s infinite;
background-color: #1e87f0;
}
@keyframes refresh {
from {
width: 100%;
}
to {
width: 0;
}
}
虽然,我确实担心同步问题,因为动画没有以updatePassword
任何方式耦合。
问题:有没有办法在updatePassword
我每次调用函数时重置动画,并消除初始延迟?
解决方案
我已经修改了你的JSFiddle,这里是解释。
#countdown-fill {
width: 100%;
height: 100%;
transform-origin: left;
background-color: #1e87f0;
}
.reset {
transition: transform 5s linear;
transform: scaleX(0);
}
诀窍是将转换绑定到一个类,当您想重置它时,只需删除该类(将转换重置为初始状态)并再次添加它(重新启动它)。
但是有一些陷阱:最重要的是立即删除和添加类将由浏览器优化,它只会合并操作,根本不会发生任何转换。诀窍是将调用包装在嵌套的 rAF 调用中,这将强制浏览器执行、渲染,然后再次执行。
window.requestAnimationFrame(function() {
document.getElementById("countdown-fill").classList.remove('reset');
window.requestAnimationFrame(function() {
document.getElementById("countdown-fill").classList.add('reset');
});
});
第二个与过渡有关:优化浏览器渲染,避免过渡属性如宽度或高度,并尝试限制变换和不透明度。我已将您的宽度过渡更改为变换过渡:效果相同,性能更高。
推荐阅读
- multithreading - C ++ 11同时读取一个布尔值
- javascript - Firefox 和 safari 无法创建“CORS”模式的获取请求
- php - #1044 - 用户 'A WEIRD USER'@'localhost' 拒绝访问数据库 'MY DATABASE'
- android - Zipping Room Flowable 可防止更新
- ignite - 在另一个缓存的调用处理器中调用缓存删除时,Ignite 服务挂起,“条带池中可能出现饥饿”?
- macos - 如何使用 sed 替换多行
- boto3 - boto3 的 AWS SNS 和 Waiter 函数
- c# - C# 从 HTTPS URL 获取服务器证书引发 System.PlatformNotSupportedException 异常
- javascript - 如何使用正则表达式在javascript中通过id获取元素?
- listview - 将自定义命令的工具提示添加到列表项的上下文菜单