// Text write
var TxtType = function (el, toRotate, period) {
this.toRotate = toRotate;
this.el = el;
this.loopNum = 0;
this.period = parseInt(period, 10) || 2000;
this.txt = "";
this.tick();
this.isDeleting = !1;
};
TxtType.prototype.tick = function () {
var i = this.loopNum % this.toRotate.length;
var fullTxt = this.toRotate[i];
if (this.isDeleting) {
this.txt = fullTxt.substring(0, this.txt.length - 1);
} else {
this.txt = fullTxt.substring(0, this.txt.length + 1);
}
this.el.innerHTML = '<span class="wrap">' + this.txt + "</span>";
var that = this;
var delta = 200 - Math.random() * 100;
if (this.isDeleting) {
delta /= 2;
}
if (!this.isDeleting && this.txt === fullTxt) {
delta = this.period;
this.isDeleting = !0;
} else if (this.isDeleting && this.txt === "") {
this.isDeleting = !1;
this.loopNum++;
delta = 500;
}
setTimeout(function () {
that.tick();
}, delta);
};
window.onload = function () {
var elements = document.getElementsByClassName("typewrite");
for (var i = 0; i < elements.length; i++) {
var toRotate = elements[i].getAttribute("data-type");
var period = elements[i].getAttribute("data-period");
if (toRotate) {
new TxtType(elements[i], JSON.parse(toRotate), period);
}
}
var css = document.createElement("style");
css.txt = "text/css";
css.innerHTML = ".typewrite > .wrap { border-right: 0.08em solid #fff}";
document.body.appendChild(css);
};
i'm making this javascript typewriting effect using json and css with 3 elements in it
<a class="typewrite color-linear" href="/" data-period="3000" data-type="["Dhruv Verma", "Designer", "Creator"]"></a>
but i'm constanty getting this error, which says json ended unexpectedly, i dont know what exactly it means please help, frequent help will be appriciated
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I found this code but I could not figure out how to make the cursor blink
var TxtType = function(el, toRotate, period) {
this.toRotate = toRotate;
this.el = el;
this.loopNum = 0;
this.period = parseInt(period, 10) || 2000;
this.txt = '';
this.tick();
this.isDeleting = false;
};
TxtType.prototype.tick = function() {
var i = this.loopNum % this.toRotate.length;
var fullTxt = this.toRotate[i];
if (this.isDeleting) {
this.txt = fullTxt.substring(0, this.txt.length - 1);
} else {
this.txt = fullTxt.substring(0, this.txt.length + 1);
}
this.el.innerHTML = '<span class="wrap">' + this.txt + '</span>';
var that = this;
var delta = 200 - Math.random() * 100;
if (this.isDeleting) {
delta /= 2;
}
if (!this.isDeleting && this.txt === fullTxt) {
delta = this.period;
this.isDeleting = true;
} else if (this.isDeleting && this.txt === '') {
this.isDeleting = false;
this.loopNum++;
delta = 500;
}
setTimeout(function() {
that.tick();
}, delta);
};
window.onload = function() {
var elements = document.getElementsByClassName('typewrite');
for (var i = 0; i < elements.length; i++) {
var toRotate = elements[i].getAttribute('data-type');
var period = elements[i].getAttribute('data-period');
if (toRotate) {
new TxtType(elements[i], JSON.parse(toRotate), period);
}
}
// INJECT CSS
var css = document.createElement("style");
css.type = "text/css";
css.innerHTML = ".typewrite > .wrap { border-right: 0.05em solid #32CD32}";
document.body.appendChild(css);
};
<a href="pages/guitar.html" target="_self">
<h5 class="typewrite" data-period="2000" data-type='[ "fundamental", "simplified" ]'>
<span class="wrap blink-caret"></span>
</h5>
</a>
I found a simple way to do it with a CSS blinking right-border.
It blinks every 0.5s, however, the <span> gets reconstructed every time a letter is typed, so the CSS timer resets. You can see the cursor blinking when the letters pause typing and wait for more than 0.5s.
var TxtType = function(el, toRotate, period) {
this.toRotate = toRotate;
this.el = el;
this.loopNum = 0;
this.period = parseInt(period, 10) || 2000;
this.txt = '';
this.tick();
this.isDeleting = false;
};
TxtType.prototype.tick = function() {
var i = this.loopNum % this.toRotate.length;
var fullTxt = this.toRotate[i];
if (this.isDeleting) {
this.txt = fullTxt.substring(0, this.txt.length - 1);
} else {
this.txt = fullTxt.substring(0, this.txt.length + 1);
}
this.el.innerHTML = '<span class="wrap">' + this.txt + '</span>';
var that = this;
var delta = 200 - Math.random() * 100;
if (this.isDeleting) {
delta /= 2;
}
if (!this.isDeleting && this.txt === fullTxt) {
delta = this.period;
this.isDeleting = true;
} else if (this.isDeleting && this.txt === '') {
this.isDeleting = false;
this.loopNum++;
delta = 500;
}
setTimeout(function() {
that.tick();
}, delta);
};
window.onload = function() {
var elements = document.getElementsByClassName('typewrite');
for (var i = 0; i < elements.length; i++) {
var toRotate = elements[i].getAttribute('data-type');
var period = elements[i].getAttribute('data-period');
if (toRotate) {
new TxtType(elements[i], JSON.parse(toRotate), period);
}
}
};
.typewrite > .wrap {
animation: blink .5s step-end infinite alternate;
border-right: solid 3px #32CD32;
}
#keyframes blink {
50% {
border-color: transparent;
}
}
<a href="pages/guitar.html" target="_self">
<h5 class="typewrite" data-period="2000" data-type='[ "fundamental", "simplified" ]'>
<span class="wrap blink-caret"></span>
</h5>
</a>
I have this piece of code to create a typing carousel effect for my webpage. I'm trying to make it so that the carousel stops once it reaches the last string in the array. But I'm having trouble locating where the infinite loop is?
Since there's no while or for loop, I'm confused as to how this is even repeating. Could someone give me pointers?
var TxtRotate = function(el, toRotate, period) {
this.toRotate = toRotate;
this.el = el;
this.loopNum = 0;
this.period = parseInt(period, 10) || 2000;
this.txt = '';
this.tick();
this.isDeleting = false;
return;
};
TxtRotate.prototype.tick = function() {
var i = this.loopNum % this.toRotate.length;
var fullTxt = this.toRotate[i];
if (this.isDeleting) {
this.txt = fullTxt.substring(0, this.txt.length - 1);
} else {
this.txt = fullTxt.substring(0, this.txt.length + 1);
}
this.el.innerHTML = '<span class="wrap">' + this.txt + '</span>';
var that = this;
var delta = 80;
if (this.isDeleting) {
delta /= 2;
}
if (!this.isDeleting && this.txt === fullTxt) {
delta = this.period;
this.isDeleting = true;
} else if (this.isDeleting && this.txt === '') {
this.isDeleting = false;
this.loopNum++;
delta = 200;
}
setTimeout(function() {
that.tick();
}, delta);
};
window.onload = function() {
var elements = document.getElementsByClassName('txt-rotate');
var toRotate = elements[0].getAttribute('data-rotate');
var period = elements[0].getAttribute('data-period');
if (toRotate) {
new TxtRotate(elements[0], JSON.parse(toRotate), period);
}
// INJECT CSS
var css = document.createElement("style");
css.type = "text/css";
css.innerHTML = ".txt-rotate > .wrap { border-right: 0.08em solid #666 }";
document.body.appendChild(css);
return;
};
It uses some kind of clock that "rewinds" itself.
The end of tick is this :
setTimeout(function() {
that.tick();
}, delta);
It means that when the function tick ends, it schedules itself to be called again after delta time.
See setTimeout documentation if you are not familiar with this (very useful) JavaScript function.
If you want to make it stop repeating itself, just wrap the above lines in an if block with your continuation condition, and you're good to go.
The very first call to tick happens when the object TxtRotate is created, in the constructor.
I am using a typewriter effect from this codepen.
var TxtType = function(el, toRotate, period) {
this.toRotate = toRotate;
this.el = el;
this.loopNum = 0;
this.period = parseInt(period, 10) || 2000;
this.txt = '';
this.tick();
this.isDeleting = false;
};
TxtType.prototype.tick = function() {
var i = this.loopNum % this.toRotate.length;
var fullTxt = this.toRotate[i];
if (this.isDeleting) {
this.txt = fullTxt.substring(0, this.txt.length - 1);
} else {
this.txt = fullTxt.substring(0, this.txt.length + 1);
}
this.el.innerHTML = '<span class="wrap">'+this.txt+'</span>';
var that = this;
var delta = 200 - Math.random() * 100;
if (this.isDeleting) { delta /= 2; }
if (!this.isDeleting && this.txt === fullTxt) {
delta = this.period;
this.isDeleting = true;
} else if (this.isDeleting && this.txt === '') {
this.isDeleting = false;
this.loopNum++;
delta = 500;
}
setTimeout(function() {
that.tick();
}, delta);
};
window.onload = function() {
var elements = document.getElementsByClassName('typewrite');
for (var i=0; i<elements.length; i++) {
var toRotate = elements[i].getAttribute('data-type');
var period = elements[i].getAttribute('data-period');
if (toRotate) {
new TxtType(elements[i], JSON.parse(toRotate), period);
}
}
// INJECT CSS
var css = document.createElement("style");
css.type = "text/css";
css.innerHTML = ".typewrite > .wrap { border-right: 0.08em solid #fff}";
document.body.appendChild(css);
};
Problem is, I am very new to JavaScript. Currently, the typing loops infinitely. I would like it to just play once through and then stop (leaving the last set of text on the page). How do I do that?
Quick'n'dirty:
Replace
if (!this.isDeleting && this.txt === fullTxt) {
delta = this.period;
this.isDeleting = true;
}
By
if (!this.isDeleting && this.txt === fullTxt) {
return;
}
I found this typewriting effect on Codepen, which works great, however, I'm trying to stop the loop so the typewriting effect only loads once and no more. I tried asking the author but no answer. Can you point me in the right direction? Here's the link to the original https://codepen.io/Tbgse/pen/dYaJyJ
// function([string1, string2],target id,[color1,color2])
consoleText(['Divi Notes.', 'Divi Tips and Tricks', 'Made with Love.'], 'text', ['#BD6983', 'tomato', 'lightblue']);
function consoleText(words, id, colors) {
if (colors === undefined) colors = ['#fff'];
var visible = true;
var con = document.getElementById('console');
var letterCount = 1;
var x = 1;
var waiting = false;
var target = document.getElementById(id)
target.setAttribute('style', 'color:' + colors[0])
window.setInterval(function() {
if (letterCount === 0 && waiting === false) {
waiting = true;
target.innerHTML = words[0].substring(0, letterCount)
window.setTimeout(function() {
var usedColor = colors.shift();
colors.push(usedColor);
var usedWord = words.shift();
words.push(usedWord);
x = 1;
target.setAttribute('style', 'color:' + colors[0])
letterCount += x;
waiting = false;
}, 1000)
} else if (letterCount === words[0].length + 1 && waiting === false) {
waiting = true;
window.setTimeout(function() {
x = -1;
letterCount += x;
waiting = false;
}, 1000)
} else if (waiting === false) {
target.innerHTML = words[0].substring(0, letterCount)
letterCount += x;
}
}, 120)
window.setInterval(function() {
if (visible === true) {
con.className = 'console-underscore hidden'
visible = false;
} else {
con.className = 'console-underscore'
visible = true;
}
}, 400)
}
You literally need to comment out one line of code:
// function([string1, string2],target id,[color1,color2])
consoleText(['Divi Notes.', 'Divi Tips and Tricks', 'Made with Love.'], 'text', ['#BD6983', 'tomato', 'lightblue']);
function consoleText(words, id, colors) {
if (colors === undefined) colors = ['#fff'];
var visible = true;
var con = document.getElementById('console');
var letterCount = 1;
var x = 1;
var waiting = false;
var target = document.getElementById(id)
target.setAttribute('style', 'color:' + colors[0])
window.setInterval(function() {
if (letterCount === 0 && waiting === false) {
waiting = true;
target.innerHTML = words[0].substring(0, letterCount)
window.setTimeout(function() {
var usedColor = colors.shift();
colors.push(usedColor);
var usedWord = words.shift();
//words.push(usedWord); <--- This one right here!
x = 1;
target.setAttribute('style', 'color:' + colors[0])
letterCount += x;
waiting = false;
}, 1000)
} else if (letterCount === words[0].length + 1 && waiting === false) {
waiting = true;
window.setTimeout(function() {
x = -1;
letterCount += x;
waiting = false;
}, 1000)
} else if (waiting === false) {
target.innerHTML = words[0].substring(0, letterCount)
letterCount += x;
}
}, 120)
}
The general mechanics:
var usedWord = words.shift();
words.push(usedWord);
Takes the next word to say and then adds it to the end of the array. Assuming this is what keeps track of the words, to stop it at the very end simply remove the push
var usedWord = words.shift();
//words.push(usedWord);
As #mark_m says you should also stop the setInterval:
// function([string1, string2],target id,[color1,color2])
consoleText(['Divi Notes.', 'Divi Tips and Tricks', 'Made with Love.'], 'text', ['#BD6983', 'tomato', 'lightblue']);
function consoleText(words, id, colors) {
if (colors === undefined) colors = ['#fff'];
var visible = true;
var con = document.getElementById('console');
var letterCount = 1;
var x = 1;
var waiting = false;
var target = document.getElementById(id)
target.setAttribute('style', 'color:' + colors[0])
var interval = window.setInterval(function() {
if (letterCount === 0 && waiting === false) {
waiting = true;
target.innerHTML = words[0].substring(0, letterCount)
window.setTimeout(function() {
var usedColor = colors.shift();
colors.push(usedColor);
var usedWord = words.shift();
//words.push(usedWord); <--- This one right here!
if(words.length==0) clearInterval(interval)
x = 1;
target.setAttribute('style', 'color:' + colors[0])
letterCount += x;
waiting = false;
}, 1000)
} else if (letterCount === words[0].length + 1 && waiting === false) {
waiting = true;
window.setTimeout(function() {
x = -1;
letterCount += x;
waiting = false;
}, 1000)
} else if (waiting === false) {
target.innerHTML = words[0].substring(0, letterCount)
letterCount += x;
}
}, 120)
}
P.S. I realise this is your first post, but this is not a coding service. Show us how you tried to fix the issue. Otherwise you are unlikely to get a real response.
I'm not sure if you need the underscore at the end blinking or not so I just left it there.
Following changes are needed
Comment out the circular insertion into the arrays.
var usedColor = colors.shift();
//colors.push(usedColor);
var usedWord = words.shift();
//words.push(usedWord);
Stop interval at the the end of the array
var wordsInterval = window.setInterval(function() {
if(words.length == 0) {
window.clearInterval(wordsInterval);
return;
}
Here's whole code (working link https://codepen.io/anon/pen/LrqmPg)
// function([string1, string2],target id,[color1,color2])
consoleText(['Hello World.', 'Console Text', 'Made with Love.'], 'text',['tomato','rebeccapurple','lightblue']);
function consoleText(words, id, colors) {
if (colors === undefined) colors = ['#fff'];
var visible = true;
var con = document.getElementById('console');
var letterCount = 1;
var x = 1;
var waiting = false;
var target = document.getElementById(id)
target.setAttribute('style', 'color:' + colors[0])
var wordsInterval = window.setInterval(function() {
if(words.length == 0) {
window.clearInterval(wordsInterval);
return;
}
if (letterCount === 0 && waiting === false) {
waiting = true;
target.innerHTML = words[0].substring(0, letterCount)
window.setTimeout(function() {
var usedColor = colors.shift();
//colors.push(usedColor);
var usedWord = words.shift();
//words.push(usedWord);
x = 1;
target.setAttribute('style', 'color:' + colors[0])
letterCount += x;
waiting = false;
}, 1000)
} else if (letterCount === words[0].length + 1 && waiting === false) {
waiting = true;
window.setTimeout(function() {
x = -1;
letterCount += x;
waiting = false;
}, 1000)
} else if (waiting === false) {
target.innerHTML = words[0].substring(0, letterCount)
letterCount += x;
}
}, 120)
window.setInterval(function() {
if (visible === true) {
con.className = 'console-underscore hidden'
visible = false;
} else {
con.className = 'console-underscore'
visible = true;
}
}, 400)
}
#import url(https://fonts.googleapis.com/css?family=Khula:700);
body {
background: #111;
}
.hidden {
opacity:0;
}
.console-container {
font-family:Khula;
font-size:4em;
text-align:center;
height:200px;
width:600px;
display:block;
position:absolute;
color:white;
top:0;
bottom:0;
left:0;
right:0;
margin:auto;
}
.console-underscore {
display:inline-block;
position:relative;
top:-0.14em;
left:10px;
}
<div class='console-container' id='console-container'><span id='text'></span><div class='console-underscore' id='console'>_</div></div>
Edit: Without erasure (https://codepen.io/anon/pen/eKxrvM)
// function([string1, string2],target id,[color1,color2])
consoleText(['Hello World.', 'Console Text.', 'Made with Love.'], 'console-container',['tomato','rebeccapurple','lightblue']);
function consoleText(words, containerId, colors) {
if (colors === undefined) colors = ['#fff'];
var visible = true;
var con = document.getElementById('console');
var letterCount = 1;
var x = 1;
var waiting = false;
var container = document.getElementById(containerId);
var targets = [];
words.forEach(() => {
var newTarget = document.createElement('span');
targets.unshift(newTarget);
container.prepend(newTarget);
});
var target = targets.shift();
target.setAttribute('style', 'color:' + colors[0])
var wordsInterval = window.setInterval(function() {
if(words.length == 0) {
window.clearInterval(wordsInterval);
return;
}
if (letterCount === 0 && waiting === false) {
waiting = true;
targets.length && (target = targets.shift());
//target.innerHTML = words[0].substring(0, letterCount)
window.setTimeout(function() {
var usedColor = colors.shift();
//colors.push(usedColor);
var usedWord = words.shift();
//words.push(usedWord);
x = 1;
target.setAttribute('style', 'color:' + (colors.length == 0? usedColor: colors[0]))
letterCount += x;
waiting = false;
}, 1000)
} else if (letterCount === words[0].length + 1 && waiting === false) {
waiting = false;
letterCount = 0;
} else if (waiting === false) {
target.innerHTML = words[0].substring(0, letterCount)
letterCount += x;
}
}, 120)
window.setInterval(function() {
if (visible === true) {
con.className = 'console-underscore hidden'
visible = false;
} else {
con.className = 'console-underscore'
visible = true;
}
}, 400)
}
#import url(https://fonts.googleapis.com/css?family=Khula:700);
body {
background: #111;
}
.hidden {
opacity:0;
}
.console-container {
font-family:Khula;
font-size:4em;
text-align:center;
height:200px;
width:600px;
display:block;
position:absolute;
color:white;
top:0;
bottom:0;
left:0;
right:0;
margin:auto;
}
.console-underscore {
display:inline-block;
position:relative;
top:-0.14em;
left:10px;
}
<div class='console-container' id='console-container'><span id='text'></span><div class='console-underscore' id='console'>_</div></div>
just remove push() into words array, comment the following line, it is enough to typewrite it once.
words.push(usedWord);
PS: Clear interval should be used to avoid calling the function code again.
if(!words || words.length == 0){
clearInterval(t);
return;
}
Check Codepen for the demo