I have functions for printing text by step printing text. And the event that happens when you click on the button (that’s when the function is triggered). BUT if you press the button several times, the text will be printed on top of another one. If anyone has any ideas what to do with this, I really ask for help. And, if possible, give advice on the code.
function printText(element) {
element.text('')
const text = element.attr('data-text')
let counter = 0
let newText = ''
const print = setInterval(() => {
if(counter <= text.length && text[counter] != undefined){
newText = newText + text[counter]
counter++
}else{clearInterval(print)}
element.text(newText)
}, 30)
}
accordingButtons.click(function(e){
const $target = $(this)
const $targetBody = $target.attr('class') === 'polygon-but' ? $target.parent().parent().next() : $target.parent().next()
if($target.attr('data-toggle') == 'true'){
$targetBody.animate({
opacity: 0.0,
height: `0px`,
marginTop : '0px'
}, 200)
$target.attr('data-toggle', 'false')
}
else if($target.attr('data-toggle') == 'false'){
$targetBody.animate({
opacity: 1,
height: `+=${$targetBody.attr('data-number')}`,
marginTop : '37px'
}, 200)
$target.attr('data-toggle', 'true')
printText($targetBody)
}
})
>Solution :
Move the intervalID outside the function and add a clearInterval before the setInterval
let print;
function printText(element) {
element.text('')
const text = element.attr('data-text')
let counter = 0
let newText = ''
clearInterval(print)
print = setInterval(() => {
if (counter <= text.length && text[counter] != undefined) {
newText = newText + text[counter]
counter++
} else {
clearInterval(print)
}
element.text(newText)
}, 100)
}
printText($("[data-text"));
// simulate a second click
setTimeout(() => printText($("[data-text")),1000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div data-text="Never gonna give you up"></div>