Skip to content

Instantly share code, notes, and snippets.

@MarkTiedemann
Last active August 24, 2019 15:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MarkTiedemann/2e46777d54ebc125e629ecbbbda57b27 to your computer and use it in GitHub Desktop.
Save MarkTiedemann/2e46777d54ebc125e629ecbbbda57b27 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<span>for </span><span id="typer"></span>
<script>
var target = document.getElementById("typer");
var texts = [
["developers", "☕"],
["beginners", "🔥"],
["unicorns", "🦄"],
["hackers", "💀"],
["everyone", "❤️"]
];
var text = "",
i = 0,
j = 0,
forward = true,
wait = false;
function next() {
wait = false;
if (i === texts.length) i = 0;
text = texts[i][0];
if (j === text.length) {
forward = false;
wait = true;
j--;
return text + " " + texts[i][1];
}
if (j === -1) {
forward = true;
wait = true;
j = 0;
i++;
return "";
}
return text.slice(0, forward ? ++j : j--);
}
function delay() {
return Math.floor(
Math.random() * (forward ? 350 : 100)
) + (wait ? 600 : (forward ? 100 : 50));
}
function type() {
target.textContent = next();
setTimeout(type, delay());
}
setTimeout(type, 450);
</script>
@HendrikRunte
Copy link

Wie wäre es in ES6?

class Typer {
  constructor(selector) {
    this.words = {
      'developers ': '☕',
      'beginners': '🔥',
      'unicorns': '🦄',
      'hackers': '💀',
      'everyone': '❤'
    };
    this.forward = true;
    this.wait = false;

    this.i = 0;
    this.j = 0;

    [...document.querySelectorAll(selector)].forEach(e => {
      setTimeout(this.typing(e), 450);
    });
  }

  delay() {
    return Math.floor(
          Math.random() * (this.forward ? 350 : 100)
        ) + (this.wait ? 600 : (this.forward ? 100 : 50));
  }

  nextWord() {
    let word = '';

    if (this.i === this.words.length) this.i = 0;

    word = Object.keys(this.words)[this.i];

    if (this.j === word.length) {
      this.forward = false;
      this.wait = true;
      this.j--;
      return `${word} ${this.words[Object.keys(this.words)[this.i]]}`;
    }

    if (this.j === -1) {
      this.forward = true;
      this.wait = true;
      this.j = 0;
      this.i++;
      return '';
    }

    return word.slice(0, this.forward ? ++this.j : this.j--);
  }

  typing(e) {
    e.textContent = this.nextWord();
    setTimeout(() => { this.typing(e) }, this.delay());
  }
}

{
  new Typer('#typer');
}

@MarkTiedemann
Copy link
Author

MarkTiedemann commented Aug 23, 2019

Not sure this is a case where ES6 makes sense. First of all, it's 25% more code according to bytesizematters (611B -> 843B, ignoring whitespace). And maybe that's just me, but I find it harder to read this.varName rather than just varName. Also, classes, rest params, let/const, etc. have pretty good browser support (roughly 90% according to caniuse) - but, depending on the target group, you might still want to transpile them, which comes with a whole new set of issues... Don't get me wrong, I love ES6. But for a very simple example like this, I don't think it's necessarily worth it.

@HendrikRunte
Copy link

As you wish :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment