CSSとJavaScriptを使用して(ビデオゲームのキャプションなど)文字ごとにHTMLテキストを表示する最もエレガントな方法は何ですか?
彼はブルートフォースアプローチ(たとえば、jQuery.append()
を使用して文字を分割して1つずつ印刷する)を使用して解決できると確信していますが、CSS3(擬似要素? )またはこれをよりエレガントに行うためのJQueryマジック。
ソリューションが内部HTMLコンテンツを考慮する場合の追加ポイント。
HTML
<div id="msg"/>
Javascript
var showText = function (target, message, index, interval) {
if (index < message.length) {
$(target).append(message[index++]);
setTimeout(function () { showText(target, message, index, interval); }, interval);
}
}
で呼び出す:
$(function () {
showText("#msg", "Hello, World!", 0, 500);
});
スムーズな公開が合理的である場合、これは非常に簡単なはずです。テストされていないが、これは私がそれがうまくいくと思う方法です
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 );
さて、私は抵抗することができず、フィドルを作りました。私が修正した1つの小さなコードエラー。私にはいいですね!
本当にappend
、または表示/非表示にするだけです。
ただし、何らかの奇妙な理由でテキストを変更したくない場合は、次のコードを使用して、理由があまりにも複雑で、理由がありません。
HTML:
<p>I'm moving slowly...<span class="cover"></span></p>
CSS:
p {
font-family: monospace;
float: left;
padding: 0;
position: relative;
}
.cover {
height: 100%;
width: 100%;
background: #fff;
position: absolute;
top: 0;
right: 0;
}
jQuery:
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();
そして最後に、ここにフィドルがあります: http://jsfiddle.net/dDGVH/236/
しかし、真剣に、これを使用しないでください...
100%バニラジャバスクリプト、厳格モード、控えめな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);
そのための小さな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);
};
使い方はこれと同じくらい簡単です:
$('h1').retype();
私がこれをしたとき、私は文字がこれを回避するように見えたので、1つの行の終わりから次の行の物beいにWordがジャンプする問題に遭遇しましたもう1つは表示され、単純に文字を1つずつ、不可視のスパンから可視に移動します。 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)
反復ごとにプロミスを準備してコードをよりエレガントにし、DOMロジックを挿入できる2番目のステップとしてそれらを実行します。
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>
@ armen.shimoonの答えのバニラJavaScriptバージョン:
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>
これは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);
}
}
message [index ++]はjquery Webページで機能していませんでした-substrに変更する必要がありました。また、私の元のテキストはHTMLを使用し、入力されるテキストはHTMLフォーマット(br、bなど)を使用します。また、ターゲットが非表示になっている場合、関数が停止します。
バニラ
(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);
})();
dOMを変更するには少しのリソースが必要なため、このコードを変更することで改善できます。
匿名のhtml要素はスタイルを設定できないため、spanタグで各文字をラップする必要があります。その後、一度に1つのスパンを明らかにします。これにより、いくつかのinnerText/innerHTMLの問題(DOMのリフローはありませんか?)は回避されますが、場合によってはやり過ぎになる可能性があります。
here :これは、.animate()プロパティを使用して各文字を操作する方法であり、テキストをsなどで覆うようなハックではありません。
私は同じ問題を解決しようとしていましたが、私はこの解決策を思いつきました。
HTML
<div id='target'></div>
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);
});
入力する答えは、答えです 文字ごとにテキスト文字を表示する ですが、いくつかの変更を加えました
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;
}