Show text letter by letter

前端 未结 16 1453
旧巷少年郎
旧巷少年郎 2020-11-27 16:38

What is the most elegant way of showing an html text letter by letter (like videogame captions) using CSS and JavaScript?

While I\'m sure that his can be solved usin

相关标签:
16条回答
  • 2020-11-27 17:00

    The answer I will type is the answer Show text letter by letter , but I made some changes to it

    HTML

    <h1>
        <span id="msg"></span>
    </h1>
    

    Javacript

    var showText = function (target, message, index, interval) {    
      if (index < message.length) { 
        //$(target).append(message[index++]);
        $(target).text($(target).text() + message[index++]);
        setTimeout(function () { showText(target, message, index, interval); }, interval); 
      } 
    }
    
    $(function () { 
      showText("#msg", "Hello, World!", 0, 80);    
      //showText("#msg", "Hello, World!", 0, 500);
    }); 
    

    CSS

    #msg {
        color: #6d67c6;
        font-family: sans-serif;
        font-size: 30px;
        font-weight: bold;
    }
    
    0 讨论(0)
  • 2020-11-27 17:01

    If a smooth reveal is reasonable then I think this should be pretty straightforward. Untested, but this is how I imagine it would work

    html

    <div id="text"><span>The intergalactic space agency</span></div>
    

    css

    div#text { width: 0px; height: 2em; white-space: nowrap; overflow: hidden;  }
    

    jQuery

    var spanWidth = $('#test span').width();
    $('#text').animate( { width: spanWidth }, 1000 );
    

    Okay, I couldn't resist and made a fiddle. One little code error that I fixed. Looks good to me though!

    http://jsfiddle.net/mrtsherman/6qQrN/1/

    0 讨论(0)
  • 2020-11-27 17:03

    Make your code more elegant by preparing promises for each iteration, then execute them as second step where you can inject DOM logic.

    const message = 'Solution using Promises';
    
    const typingPromises = (message, timeout) =>
      [...message].map(
        (ch, i) =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve(message.substring(0, i + 1));
            }, timeout * i);
          })
      );
    
    typingPromises(message, 140).forEach(promise => {
      promise.then(portion => {
        document.querySelector('p').innerHTML = portion;
      });
    });
    <div ><p></p></div>

    0 讨论(0)
  • 2020-11-27 17:03

    Vanilla JavaScript version of @armen.shimoon's answer:

    document.addEventListener('DOMContentLoaded', function() {
    
        showText("#msg", "Hello, World!", 0, 100);
    
    });
    
    let showText = function (target, message, index, interval) {
        if (index < message.length) {
            document.querySelector(target).innerHTML =
                document.querySelector(target).innerHTML + message[index++];
            setTimeout(function () { showText(target, message, index, interval); }, interval);
        }
    }
    <div id="msg"></div> 
    <span id="text_target"></span>

    0 讨论(0)
  • 2020-11-27 17:03

    there is a good answer how to do it here: this is a way that you can manipulate each letter with any .animate() property available, not with hacks like covering the text with s etc.

    0 讨论(0)
  • 2020-11-27 17:05

    When I did this I ran into the problem of a word jumping from the end of one line to the begging of the next as it the letters appeared to get around this I used to side by side spans, one of which the text was transparent, the other visible and simply moved letters one by one from the invisible span to the visible. Here's a fiddle.

    HTML

    <div class='wrapper'>
      <span class='visible'></span><span class='invisible'></span>
    </div>
    

    CSS

    .visible {
      color: black;
    } 
    
    .invisible {
      color: transparent;
    }
    

    JS

    var text = "Whatever you want your text to be here",
        soFar = "";
    
    var visible = document.querySelector(".visible"),
        invisible = document.querySelector(".invisible");
    
    invisible.innerHTML = text;
    var t = setInterval(function(){
      soFar += text.substr(0, 1),
      text = text.substr(1);
    
      visible.innerHTML = soFar;
      invisible.innerHTML = text;
    
      if (text.length === 0) clearInterval(t);
    }, 100)
    
    0 讨论(0)
提交回复
热议问题