简体   繁体   中英

Stop loop in typewriting effect using JS

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) 
}

PS 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

  1. Comment out the circular insertion into the arrays.
var usedColor = colors.shift();
    //colors.push(usedColor);
    var usedWord = words.shift();
    //words.push(usedWord);
  1. 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'>&#95;</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'>&#95;</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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM