使用 class 在每个元素上键入动画
typing animation on each element with its class
我正在尝试制作打字动画,但它不起作用,我也不知道为什么。我知道我可以在 CSS 中完成,但我想在 JS 中尝试。问题可能是函数本身我不是 JS 中最好的。
<p class="typing-animation">this will be animated</p>
<p class="typing-animation">this aswell</p>
<script>
const sleep = (ms) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
const toType = document.getElementsByClassName("typing-animation");
document.getElementsByClassName("typing-animation").textContent = "";
(async (toType) => {
for (let each of toType) {
text = each.textContent;
each.textContent = "";
let i = 0;
for (let every of text) {
every.textContent += text[i];
await sleep(200);
i++;
}
}
})(toType);
</script>
你走在正确的道路上。为了便于阅读,我刚刚清理了一些内容。
这是它的一个代码框:https://codesandbox.io/s/typing-animation-kdn8v
我假设您希望动画并行发生。出于这个原因,我们希望 运行 遍历每个 HTML 元素并在每个元素上调用我们的 animateType
函数而不等待。
每次调用 animateType
都意味着此 HTML 元素有此函数 运行ning 的副本。这样,函数内部的 text
等变量就不会在 HTML 元素之间混淆。这称为“关闭”。函数“实例”内的所有变量,仅存在于该函数实例内。
我们存储原始文本,然后清除 HTML 元素的内容,然后就像您所做的一样,我们循环缓存文本的字母,并将每个字母添加到 HTML 元素。
// Whosebug:
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const clearAndCache = (elements) => {
let cachedText = [];
for (let element of elements) {
cachedText.push(element.textContent);
element.textContent = "";
}
return cachedText;
};
const animateTypeSync = async (typeables, ms) => {
const cachedText = clearAndCache(typeables);
for (let i = 0; i < typeables.length; i++) {
for (let character of cachedText[i]) {
typeables[i].textContent += character;
await sleep(ms);
}
}
};
const animateTypeAsync = (typeables, ms) => {
const cachedText = clearAndCache(typeables);
Array.from(typeables).forEach(async (element, i) => {
for (let character of cachedText[i]) {
element.textContent += character;
await sleep(ms);
}
});
};
const elementsSync = document.getElementsByClassName("typing-animation-sync");
animateTypeSync(elementsSync, 200);
const elementsAsync = document.getElementsByClassName("typing-animation");
animateTypeAsync(elementsAsync, 150);
<!DOCTYPE html>
<html>
<head>
<title>Typing Animation</title>
<meta charset="UTF-8" />
</head>
<body>
<h1>Typing Animations</h1>
<div style="width: 100%; display: inline-flex;">
<div style="width: 50%;">
<h2>Async</h2>
<p class="typing-animation">These will run</p>
<p class="typing-animation">at the same time</p>
</div>
<div style="width: 50%;">
<h2>Sync</h2>
<p class="typing-animation-sync">These will animate</p>
<p class="typing-animation-sync">one at a time</p>
</div>
</div>
</body>
<script src="src/index.js"></script>
</html>
编辑:在 OP 发表评论后将同步版本添加到代码中。
我想这就是你想要的?
<p class="typing-animation">this will be animated</p>
<p class="typing-animation">this aswell</p>
<script>
const sleep = (ms) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
// This is an array of html elements, since getElementsByClassName returns an array, since there can be more than one html element with that class.
const elements = document.getElementsByClassName("typing-animation");
(async (typedElements) => {
let texts = []
for (let element of typedElements){
// The property to access the text inside the elements .innerHTML, if its a user interactuable element such as <input> or <textarea> then its .value
texts.push(element.innerHTML);
element.innerHTML = "";
}
// texts and typedElements has the same length.
for (let i = 0; i < texts.length; i++) {
for (let character of texts[i]) {
typedElements[i].innerHTML += character;
await sleep(200)
}
}
})(elements);
</script>
如果你想在多个地方实现这种效果,并且更容易实现,有一个库已经做到了,更容易定制和使用:Typed.js
<span class="typed"></span>
<script src="https://cdn.jsdelivr.net/npm/typed.js@2.0.12"></script>
<script>
// For more examples check: https://github.com/mattboldt/typed.js
// Full docs at: https://mattboldt.github.io/typed.js/docs/
const options = {
strings: ['This will be typed!', 'This too! ^500 <br> And this will go under!'],
typeSpeed: 40,
backSpeed: 40,
backDelay: 2000,
};
// We'll bind the typing animation to the .typed class.
let typed = new Typed('.typed', options);
</script>
我正在尝试制作打字动画,但它不起作用,我也不知道为什么。我知道我可以在 CSS 中完成,但我想在 JS 中尝试。问题可能是函数本身我不是 JS 中最好的。
<p class="typing-animation">this will be animated</p>
<p class="typing-animation">this aswell</p>
<script>
const sleep = (ms) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
const toType = document.getElementsByClassName("typing-animation");
document.getElementsByClassName("typing-animation").textContent = "";
(async (toType) => {
for (let each of toType) {
text = each.textContent;
each.textContent = "";
let i = 0;
for (let every of text) {
every.textContent += text[i];
await sleep(200);
i++;
}
}
})(toType);
</script>
你走在正确的道路上。为了便于阅读,我刚刚清理了一些内容。
这是它的一个代码框:https://codesandbox.io/s/typing-animation-kdn8v
我假设您希望动画并行发生。出于这个原因,我们希望 运行 遍历每个 HTML 元素并在每个元素上调用我们的 animateType
函数而不等待。
每次调用 animateType
都意味着此 HTML 元素有此函数 运行ning 的副本。这样,函数内部的 text
等变量就不会在 HTML 元素之间混淆。这称为“关闭”。函数“实例”内的所有变量,仅存在于该函数实例内。
我们存储原始文本,然后清除 HTML 元素的内容,然后就像您所做的一样,我们循环缓存文本的字母,并将每个字母添加到 HTML 元素。
// Whosebug:
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const clearAndCache = (elements) => {
let cachedText = [];
for (let element of elements) {
cachedText.push(element.textContent);
element.textContent = "";
}
return cachedText;
};
const animateTypeSync = async (typeables, ms) => {
const cachedText = clearAndCache(typeables);
for (let i = 0; i < typeables.length; i++) {
for (let character of cachedText[i]) {
typeables[i].textContent += character;
await sleep(ms);
}
}
};
const animateTypeAsync = (typeables, ms) => {
const cachedText = clearAndCache(typeables);
Array.from(typeables).forEach(async (element, i) => {
for (let character of cachedText[i]) {
element.textContent += character;
await sleep(ms);
}
});
};
const elementsSync = document.getElementsByClassName("typing-animation-sync");
animateTypeSync(elementsSync, 200);
const elementsAsync = document.getElementsByClassName("typing-animation");
animateTypeAsync(elementsAsync, 150);
<!DOCTYPE html>
<html>
<head>
<title>Typing Animation</title>
<meta charset="UTF-8" />
</head>
<body>
<h1>Typing Animations</h1>
<div style="width: 100%; display: inline-flex;">
<div style="width: 50%;">
<h2>Async</h2>
<p class="typing-animation">These will run</p>
<p class="typing-animation">at the same time</p>
</div>
<div style="width: 50%;">
<h2>Sync</h2>
<p class="typing-animation-sync">These will animate</p>
<p class="typing-animation-sync">one at a time</p>
</div>
</div>
</body>
<script src="src/index.js"></script>
</html>
编辑:在 OP 发表评论后将同步版本添加到代码中。
我想这就是你想要的?
<p class="typing-animation">this will be animated</p>
<p class="typing-animation">this aswell</p>
<script>
const sleep = (ms) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
// This is an array of html elements, since getElementsByClassName returns an array, since there can be more than one html element with that class.
const elements = document.getElementsByClassName("typing-animation");
(async (typedElements) => {
let texts = []
for (let element of typedElements){
// The property to access the text inside the elements .innerHTML, if its a user interactuable element such as <input> or <textarea> then its .value
texts.push(element.innerHTML);
element.innerHTML = "";
}
// texts and typedElements has the same length.
for (let i = 0; i < texts.length; i++) {
for (let character of texts[i]) {
typedElements[i].innerHTML += character;
await sleep(200)
}
}
})(elements);
</script>
如果你想在多个地方实现这种效果,并且更容易实现,有一个库已经做到了,更容易定制和使用:Typed.js
<span class="typed"></span>
<script src="https://cdn.jsdelivr.net/npm/typed.js@2.0.12"></script>
<script>
// For more examples check: https://github.com/mattboldt/typed.js
// Full docs at: https://mattboldt.github.io/typed.js/docs/
const options = {
strings: ['This will be typed!', 'This too! ^500 <br> And this will go under!'],
typeSpeed: 40,
backSpeed: 40,
backDelay: 2000,
};
// We'll bind the typing animation to the .typed class.
let typed = new Typed('.typed', options);
</script>