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