Reputation: 11
I'm trying to get JavaScript to change text multiple times in a single click, then go back to the original text. I can get the text to change, but not change automatically to another piece of text, or change back to the original text.
So the text would go from "original text" to "text 1" to "text 2" to "text 3" etc for as many as I need, then it would go back to "original text"
He's the current code I have so far
function changeText() {
document.getElementById('changingtext').innerHTML = 'text 1';
setTimeout("changeText()",3000);
}
And here's the html
<p id="changingtext" onclick="changeText()">original text</p>
Any help would be greatly appreciated. Thanks!
Upvotes: 1
Views: 88
Reputation: 899
The problem you're experiencing is that you call the function changeText
on both the click and the timeout
and that function changes the text so on both the click and after the timeout
you set the text to the same hardcoded value in the changeText
function.
The best solution to that is, as both IrkenInvader and Uzbekjon have already answered (at the time of writing), is to add a parameter to your changeText
function to allow for more customization. My javascript would be a tiny bit different than both, but that's more of a preference than a better solution per se, however, I will post my javascript for another reason. The resaon being that you are using setTimeout
with a string, which is the same as using eval
and that is a big no-no for many reasons, as explained in this article and many many many other ones you can easily find on Google.
For this reason I recommend this combination:
function changeText(new_text) {
var original_text = document.getElementById('changingtext').innerHTML;
document.getElementById('changingtext').innerHTML = new_text;
if (original_text != new_text) {
setTimeout(changeText.bind(this, original_text), 3000);
}
}
<p id="changingtext" onclick="changeText('text 1')">original text</p>
You can see here that function.bind
is used and this is passed as first parameter. This skips using eval
and still is able to pass function arguments to the func
specified in setTimeout
while retaining cross-browser compatibility. Past IE 9, you can also use
setTimeout(changeText, 3000, original_text);
so if you don't need IE 9 or below, that's much cleaner.
Upvotes: 0
Reputation: 4050
This solution uses an array of texts to cycle through, adding the original text as the last item in that array.
Javascript
var changeTexts = ['text 1','text 2','text 3','text 4','text 5'];
function changeText(index) {
var element = document.getElementById('changingtext');
if(index >= changeTexts.length){
changeTexts.splice(-1,1);
return;
}
if(index === 0) changeTexts.push(element.innerHTML);
element.innerHTML = changeTexts[index];
index++;
setTimeout(function(){ changeText(index); },1000);
}
HTML
<p id="changingtext" onclick="changeText(0)">original text</p>
Upvotes: 0
Reputation: 1728
Here's one way.
var originalText,
messages = ['text 1', 'text 2', 'text 3'],
currentItem = 0;
function changeText() {
// capture the original text
originalText = originalText || document.getElementById('changingtext').innerHTML;
// get element
var elem = document.getElementById('changingtext');
// Check if we hit the last message
// if so, go back to original and stop
if (currentItem >= messages.length) {
elem.innerHTML = originalText;
} else {
elem.innerHTML = messages[currentItem++];
setTimeout("changeText()", 3000);
}
}
<p id="changingtext" onclick="changeText()">original text</p>
Upvotes: 0
Reputation: 11813
If you don't mind passing arguments to your function:
function changeText(new_text) {
var original_text = document.getElementById('changingtext').innerHTML;
document.getElementById('changingtext').innerHTML = new_text;
setTimeout("changeText('"+original_text+"')",3000);
}
<p id="changingtext" onclick="changeText('text 1')">original text</p>
Upvotes: 1