Reputation: 11
I found a nice typewriter effect that prints text when you click the button and it works nicely. However if I want to create multiple buttons that print different texts using this script, it just doesn't work.
Javascript:
<script>
var i = 0;
var txt = 'Text goes here';
var speed = 20;
function typeWriter() {
if (i < txt.length) {
document.getElementById("txt").innerHTML += txt.charAt(i);
i++;
setTimeout(typeWriter, speed);
}
}
</script>
HTML:
<a href="#" onclick="typeWriter()">CLICK HERE</a>
<p id="txt"></p>
Upvotes: 0
Views: 1586
Reputation: 11592
I offer a slightly more flexible approach:
First of all, create an array of the strings you'd like to have appear with a type writer effect:
const texts = ['abcdefghijklmnopqrstuvwxyz', '1234567890`-=[]#&;./,\!"£$'];
You can see above, that the array has two strings in it. Next loop over the strings. I've done so by calling the forEach
method of the array:
texts.forEach(text =>
{
//work happens here
});
So for each of the strings, create a div
with an a
, to click on, and a p
to write in.
const div = document.createElement('div');
const a = document.createElement('a');
a.setAttribute('href', '#');
a.innerHTML = 'Type writer go!';
div.appendChild(a);
let p = document.createElement('p');
div.appendChild(p);
document.body.appendChild(div);
Then for the a
add a click listener, that will start the typewriter effect.
a.addEventListener('click', function(e)
{
e.preventDefault();
nextUpdate(p, 0, text);
});
As you can see, the click handler calls a function called nextUpdate
. This function sets the current text of the p
and sets the timeout for the next update.
function nextUpdate(p, index, text)
{
p.innerHTML = text.substr(0, index);
if(index < text.length)
{
setTimeout(nextUpdate, speed, p, index+1, text);
}
}
The if
there check to see if the string has been completely written. If it has not then the timeout is set up to call nextUpdate
again, and the same parameters are passed, but with an increase in the index
parameter, which tells the functions how much of the string to read.
const texts = ['abcdefghijklmnopqrstuvwxyz', '1234567890`-=[]#&;./,\!"£$'];
const speed = 150;
//create the document
texts.forEach(text =>
{
//create the area that the type writer will go
const div = document.createElement('div');
const a = document.createElement('a');
a.setAttribute('href', '#');
a.innerHTML = 'Type writer go!';
div.appendChild(a);
let p = document.createElement('p');
div.appendChild(p);
document.body.appendChild(div);
//set the onclick of the link
a.addEventListener('click', function(e)
{
e.preventDefault();
nextUpdate(p, 0, text);
});
});
function nextUpdate(p, index, text)
{
p.innerHTML = text.substr(0, index);
if(index < text.length)
{
setTimeout(nextUpdate, speed, p, index+1, text);
}
}
Upvotes: 0
Reputation: 876
You'll need to modify the function to look more like this (basically, everything that was global should be a parameter of the function instead)
You'll also need to change the function call a bit as a result - see the snippet below.
function typeWriter(messageToShow, targetElement, timeBetween, currentPos = 0) {
if (currentPos < messageToShow.length) {
document.getElementById(targetElement).innerHTML += messageToShow.charAt(currentPos);
currentPos++;
setTimeout(function() { typeWriter(messageToShow, targetElement, timeBetween, currentPos); }, timeBetween);
}
}
<button onclick="typeWriter('Hello world', 'demo', 100)">Click me</button>
<button onclick="typeWriter('Other message', 'demo2', 100)">click me two</button>
<p id="demo"></p>
<p id="demo2"></p>
Upvotes: 1