<span is="type-async" id="type-text">...</span>
<span class="blinking-cursor">_</span>
@import url("https://fonts.googleapis.com/css?family=Open+Sans:40")
body
padding: 0 10%
background-color: #111
color: #FFF
font-family: "Open Sans", sans-serif
font-size: 2em
line-height: 100vh
white-space: nowrap
.blinking-cursor
user-select: none
animation: blink 1s steps(2, start) infinite
@keyframes blink
to
visibility: hidden
View Compiled
async function init () {
const node = document.querySelector("#type-text")
await sleep(1000)
node.innerText = ""
await node.type('Hello, ')
while (true) {
await node.type('CodePen!')
await sleep(2000)
await node.delete('CodePen!')
await node.type('World!')
await sleep(2000)
await node.delete('World!')
}
}
// Source code 🚩
const sleep = time => new Promise(resolve => setTimeout(resolve, time))
class TypeAsync extends HTMLSpanElement {
get typeInterval () {
const randomMs = 100 * Math.random()
return randomMs < 50 ? 10 : randomMs
}
async type (text) {
for (let character of text) {
this.innerText += character
await sleep(this.typeInterval)
}
}
async delete (text) {
for (let character of text) {
this.innerText = this.innerText.slice(0, this.innerText.length -1)
await sleep(this.typeInterval)
}
}
}
customElements.define('type-async', TypeAsync, { extends: 'span' })
init()
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.