Javascript 逐字显示文本

Javascript 逐字显示文本,javascript,jquery,html,css,Javascript,Jquery,Html,Css,使用CSS和JavaScript逐字显示html文本(如视频游戏字幕)最优雅的方式是什么 虽然我确信可以使用蛮力方法(例如,使用jQuery.append())拆分字符并逐个打印),但我希望有一些CSS3(伪元素?)或jQuery魔法可以更优雅地完成这项工作 如果解决方案考虑内部HTML内容,则需要额外注意。您需要将每个字母包装在span标记中,因为匿名HTML元素无法设置样式。然后一次显示一个跨度。这避免了一些innerText/innerHTML问题(没有DOM回流?),但在您的情况下可能会

使用CSS和JavaScript逐字显示html文本(如视频游戏字幕)最优雅的方式是什么

虽然我确信可以使用蛮力方法(例如,使用
jQuery.append()
)拆分字符并逐个打印),但我希望有一些CSS3(伪元素?)或jQuery魔法可以更优雅地完成这项工作


如果解决方案考虑内部HTML内容,则需要额外注意。

您需要将每个字母包装在span标记中,因为匿名HTML元素无法设置样式。然后一次显示一个跨度。这避免了一些innerText/innerHTML问题(没有DOM回流?),但在您的情况下可能会有过大的杀伤力。

您真的应该只添加
或显示/隐藏

但是,如果出于某种奇怪的原因,您不想修改文本,那么您可以使用这段过于复杂的代码:

HTML:

<p>I'm moving slowly...<span class="cover"></span></p>
var $p = $('p'),
    $cover = $('.cover'),
    width = $p.width(),
    decrement = width / $p.text().length;

function addChar()
{        
    $cover.css('width', '-=' + decrement);

    if ( parseInt( $cover.css('width') ) < width )
    {
        setTimeout(addChar, 300);
    }
}

addChar();
jQuery:

<p>I'm moving slowly...<span class="cover"></span></p>
var $p = $('p'),
    $cover = $('.cover'),
    width = $p.width(),
    decrement = width / $p.text().length;

function addChar()
{        
    $cover.css('width', '-=' + decrement);

    if ( parseInt( $cover.css('width') ) < width )
    {
        setTimeout(addChar, 300);
    }
}

addChar();
var$p=$('p'),
$cover=$(“.cover”),
宽度=$p.width(),
减量=宽度/$p.text().长度;
函数addChar()
{        
$cover.css('width','-='+减量);
if(parseInt($cover.css('width'))
最后,这里是小提琴:

但是,说真的,不要使用这个…

HTML

<div id="msg"/>

如果一个平滑的揭示是合理的,那么我认为这应该是相当直接的。未经测试,但这是我想象的工作方式

html

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

var spanWidth = $('#test span').width();
$('#text').animate( { width: spanWidth }, 1000 );
好吧,我忍不住拉了把小提琴。我修正了一个小的代码错误。不过我觉得不错


这是基于armen.shimoon的:

var showText = function (target, message, index, interval) {    
    if (index <= message.length && $(target).is(':visible')) { 
        $(target).html(message.substr(0, index++)); 
        setTimeout(function () { showText(target, message, index, interval); }, interval); 
    } 
}
var showText=函数(目标、消息、索引、间隔){

if(index我为此制作了一个小小的jquery插件。首先,如果禁用javascript,您需要确保文本是可见的,如果不禁用,则逐个字母重新显示文本

$.fn.retype = function(delay) {
    var el = this,
        t = el.text(),
        c = t.split(''),
        l = c.length,
        i = 0;
    delay = delay || 100;
    el.empty();
    var interval = setInterval(function(){
        if(i < l) el.text(el.text() + c[i++]); 
        else clearInterval(interval);
    }, delay);
};
瓦尼拉

(function () {

var showText = function(target, msg, index, interval){

  var el = document.getElementById(target);

  if(index < msg.length){
    el.innerHTML = el.innerHTML + msg.charAt(index);
    index = index + 1;
    setTimeout(function(){
      showText(target,msg,index,interval);
    },interval);
  }

};


showText("id", "Hello, World!", 0, 50);   

})();
(函数(){
var showText=函数(目标、消息、索引、间隔){
var el=document.getElementById(目标);
如果(索引<消息长度){
el.innerHTML=el.innerHTML+msg.charAt(索引);
指数=指数+1;
setTimeout(函数(){
showText(目标、消息、索引、间隔);
},间隔);
}
};
showText(“id”,“你好,世界!”,0,50);
})();

您可以通过更改此代码来改进此代码,这样您只需获得一次el,因为修改DOM需要一些资源。

100%普通javascript、严格模式、不引人注目的html、,
function printLetterByLetter(destination, message, speed){
    var i = 0;
    var interval = setInterval(function(){
        document.getElementById(destination).innerHTML += message.charAt(i);
        i++;
        if (i > message.length){
            clearInterval(interval);
        }
    }, speed);
}

printLetterByLetter("someElement", "Hello world, bonjour le monde.", 100);

如何做到这一点,有一个很好的答案:
这是一种可以使用任何.animate()操作每个字母的方法属性可用,而不是像用s等覆盖文本这样的黑客。当我这样做时,我遇到了一个问题,一个单词从一行的末尾跳到下一行的乞讨处,因为字母似乎绕过了这一点,我习惯并排跨距,其中一个文本是透明的,另一个是可见的,只是将字母移动一个b从看不见的范围到可见的范围。这是一个

HTML

JS


我试图解决同一个问题,我想出了这个似乎有效的解决方案

HTML


jQuery

$(function() {
  var message = 'Hello world';
  var index = 0;

  function displayLetter() {
    if (index < message.length) {
      $('#target').append(message[index++]);
    }
    else{
      clearInterval(repeat);
    }
  }
  var repeat = setInterval(displayLetter, 100);
});
$(函数(){
var message='Hello world';
var指数=0;
函数displayLetter(){
if(索引<消息长度){
$('#target').append(message[index++]);
}
否则{
间隔时间(重复);
}
}
var repeat=setInterval(displayLetter,100);
});

通过为每次迭代准备承诺,使您的代码更加优雅,然后将它们作为第二步执行,您可以在其中注入DOM逻辑

const message='使用承诺的解决方案';
const typingPromises=(消息,超时)=>
[…消息].map(
(ch,i)=>
新承诺(解决=>{
设置超时(()=>{
解析(message.substring(0,i+1));
},超时*i);
})
);
输入承诺(信息,140)。forEach(承诺=>{
承诺。然后(部分=>{
document.querySelector('p')。innerHTML=部分;
});
});

现在有两个库用于此功能。有并且都允许html出现在您正在键入的内容中,以及许多其他有助于设置打字机效果动画的方法。

我将键入的答案就是答案,但我对它做了一些更改

HTML


@armen.shimoon的香草JavaScript版本的答案:

document.addEventListener('DOMContentLoaded',function(){
showText(“#msg”,“你好,世界!”,01100);
});
让showText=函数(目标、消息、索引、间隔){
if(索引<消息长度){
document.querySelector(target.innerHTML)=
document.querySelector(target.innerHTML+消息[index++];
setTimeout(函数(){showText(目标、消息、索引、间隔);},间隔);
}
}


它是否需要单个字母弹出?或者它是否可以是一个平滑的分隔符?如果平滑分隔符按顺序显示字母,是的。+1有趣的想法。遗憾的是,它同时显示了所有的行。也许可以进行一些更改。@hgpc:当然可以,但那将是invlove 2
。封面
跨距。这是一个非常有趣的想法越来越复杂。你确定你不想简单地附加吗?很可能我会使用附加,但我觉得你的想法很有趣。此外,它的优点是它保留了内部html内容。在诸如Chrome之类的浏览器中,当你在目标中输入一些html代码时,<有时是可见的…@Luke:真的很有用p添加一个小提琴!一旦它运行,您将如何阻止它继续?例如,假设在单击过程中调用它。当它运行时,用户再次单击以在第一次调用完成之前显示另一条消息。这会导致两个循环重叠。如何阻止第一个循环继续?
function printLetterByLetter(destination, message, speed){
    var i = 0;
    var interval = setInterval(function(){
        document.getElementById(destination).innerHTML += message.charAt(i);
        i++;
        if (i > message.length){
            clearInterval(interval);
        }
    }, speed);
}

printLetterByLetter("someElement", "Hello world, bonjour le monde.", 100);
<div class='wrapper'>
  <span class='visible'></span><span class='invisible'></span>
</div>
.visible {
  color: black;
} 

.invisible {
  color: transparent;
}
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)
<div id='target'></div>
$(function() {
  var message = 'Hello world';
  var index = 0;

  function displayLetter() {
    if (index < message.length) {
      $('#target').append(message[index++]);
    }
    else{
      clearInterval(repeat);
    }
  }
  var repeat = setInterval(displayLetter, 100);
});
<h1>
    <span id="msg"></span>
</h1>
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);
}); 
#msg {
    color: #6d67c6;
    font-family: sans-serif;
    font-size: 30px;
    font-weight: bold;
}
function textRoll(message, interval){
   setTimeout(() => {
         para.innerHTML += message.charAt(0);
         return textRoll(message.slice(1))
   }, interval)
}