我尝试按字符更改任何文本(按字符显示文本,按字符删除文本并按字符显示另一个字符)。
我实际上拥有什么?
var i = 0;
var terms = ['text <b>bold</b>', 'longer text <b>bold</b>', '<b>bold</b> text 3'];
var timer = setInterval(function() {
var el = $('#el');
var wr = $('#wr');
setInterval(function() {
var str = el.html(); // doesn't work (still shows all content, not sliced one)
el.html(str.substring(0, str.length - 1));
}, 300 / str.length); // (300 / str.length) - do all animation in 300s
i++;
if (i === 3) {
i = 0;
}
}, 2500);
我在切片最后一个字符时遇到问题,所以到目前为止我还没有添加新文本:-(
我尝试过的变体之一:
...
var text = terms[i].split('');
setInterval(function() {
el.html(text); // add sliced text in loop... not working as expected
// ...
text = text.slice(0, -1); // slice text by last character
}, 300 / text.length);
好的,根据评论,稍微解释一下
我有一个元素
<span id=el>text <b>bold</b></span>
在 300 毫秒的时间间隔内,我需要逐个字符地删除此文本。
<span id=el>text <b>bold</b></span>
<span id=el>text <b>bol</b></span>
<span id=el>text <b>bo</b></span>
<span id=el>text <b>b</b></span>
<span id=el>text <b></b></span> // remove 'b'
<span id=el>text</span> // remove ' ' and empty bold
<span id=el>tex</span>
<span id=el>te</span>
<span id=el>t</span>
<span id=el></span>
// now element is empty, since start it's 300ms
// and now I need to put there new text, char by char (whole phrase 300ms again)
<span id=el>l</span>
<span id=el>lo</span>
<span id=el>lon</span>
...
<span id=el>longer tex</span>
<span id=el>longer text</span>
<span id=el>longer text </span> // add space
<span id=el>longer text <b>b</b></span> // add 'b' into bold
<span id=el>longer text <b>bo</b></span>
<span id=el>longer text <b>bol</b></span>
<span id=el>longer text <b>bold</b></span>
// after 2500ms remove this char by char again and replace by third. Etc.
等等。你能帮我吗?过去两天尝试过,多次尝试,没有结果......
谢谢
最佳答案
这就是我组织代码来缩小和增大元素的方式。我能做到这一点的唯一明智的方法是首先替换 <
和>
通过相应的实体代码<
和>
这样这些字符就不会被解释为实际的标签。这些 4 个字母的实体代码将被删除并作为一个单元添加。通过这种方式,您可以将字符串从右向左一次收缩一个准字符,并且始终保持有效的 HTML。
Promise
api(实际上是 jQuery 的 $.Deferred 版本)用于能够以确定性的方式知道收缩-增长周期(这是一个异步过程)何时完成,然后开始 2500 毫秒的延迟(这是另一个异步过程),然后重新开始。
$(function() {
function shrink_grow(resolve, term)
{
term = term.replace(/</g, '<').replace(/>/g, '>');
let el = $('#el');
el.html(term);
let interval = setInterval(shrinker, 30);
function shrinker()
{
let str = el.html();
let n = str.length >= 4 && (str.endsWith('>') || str.endsWith(`<`)) ? 4 : 1;
el.html(str.substr(0, str.length - n));
if (str.length === 0) {
clearInterval(interval);
interval = setInterval(grower, 30);
}
}
function grower()
{
let str = el.html();
if (str.length == term.length) {
clearInterval(interval);
resolve(undefined); // we are done
}
else if (str.length <= term.length - 4 && (term.substr(str.length + 1, 4) == '<' || term.substr(str.length + 1, 4) == '>')) {
el.html(term.substr(0, str.length + 4));
}
else {
el.html(term.substr(0, str.length + 1));
}
}
}
function pause(milliseconds)
{
// Create a new Deferred object
var deferred = $.Deferred();
// Resolve the Deferred after the amount of time specified by milliseconds
setTimeout(deferred.resolve, milliseconds);
return deferred.promise();
}
let terms = ['text <b>bold</b>', 'longer text <i>italic</i> text', '<b>bold</b> text 3'];
let term_number = 0;
let deferred = $.Deferred();
let promise = deferred.promise();
shrink_grow(deferred.resolve, terms[term_number++]);
promise.then(function() {
pause(2500).then(function() {
let deferred = $.Deferred();
let promise = deferred.promise();
shrink_grow(deferred.resolve, terms[term_number++]);
promise.then(function() {
pause(2500).then(function() {
let deferred = $.Deferred();
let promise = deferred.promise();
shrink_grow(deferred.resolve, terms[term_number++]);
promise.then(function() {
console.log('done');
});
});
});
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span id="el"></span>
并保持标签完整
然而,这非常复杂:
$(function() {
let TOTAL_TIME = 300;
function shrink_grow(resolve, term)
{
let el = $('#el');
let matches = term.match(/<([^>])+>(.*?)<\/\1>/); // look for internal tag
let internalTagTextLength = matches ? matches[2].length : 0;
let internalTagText = internalTagTextLength ? matches[2] : '';
let strlen = term.length;
if (matches) {
strlen -= matches[1].length * 2 + 5;
}
let shrinkGrowInterval = TOTAL_TIME / strlen;
if (shrinkGrowInterval < 16) {
shrinkGrowInterval = 16;
}
let interval = setInterval(grower, shrinkGrowInterval);
function shrinker()
{
let str = el.html();
let matches = str.match(/<([^>])+>(.*?)<\/\1>$/); // <i>text</i> at end of string, for example
if (matches) {
let str2 = matches[2];
if (str2.length < 2) { // get rid of entire tag
str2 = matches[0];
let n = str2.length;
let l = str.length - n;
el.html(str.substr(0, l));
if (l === 0) {
clearInterval(interval);
resolve(undefined); // we are done
}
}
else {
let str2a = str2.substr(0, str2.length - 1);
str = str.replace(/<([^>])+>(.*?)<\/\1>$/, '<' + matches[1] + '>' + str2a + '</' + matches[1] + '>');
el.html(str);
}
}
else {
el.html(str.substr(0, str.length - 1));
if (str.length === 0) {
clearInterval(interval);
resolve(undefined); // we are done
}
}
}
function grower()
{
let str = el.html();
if (str.length == term.length) {
clearInterval(interval);
interval = setInterval(shrinker, shrinkGrowInterval);
}
else {
let matches = term.substr(str.length).match(/^<([^>])+>(.*?)<\/\1>/); // start of <i>text</i>, for example?
if (matches) {
let str2 = '<' + matches[1] + '>' + matches[2].substr(0, 1) + '</' + matches[1] + '>';
el.html(str + str2);
}
else {
let matches = str.match(/<([^>])+>(.*?)<\/\1>$/); // <i>text</i> at end of string, for example
if (matches) {
let str2 = matches[2];
let l = str2.length;
if (l == internalTagTextLength) {
el.html(term.substr(0, str.length + 1));
}
else {
let str2a = internalTagText.substr(0, l + 1);
str = str.replace(/<([^>])+>(.*?)<\/\1>$/, '<' + matches[1] + '>' + str2a + '</' + matches[1] + '>');
el.html(str);
}
}
else {
el.html(term.substr(0, str.length + 1));
}
}
}
}
}
let terms = ['text <b>bold</b>', 'longer text <i>italic</i> text', '<b>bold</b> text 3'];
let nTerms = terms.length;
let termNumber = -1;
function callShrinkGrow()
{
if (++termNumber >= nTerms) {
termNumber = 0;
}
let deferred = $.Deferred();
let promise = deferred.promise();
shrink_grow(deferred.resolve, terms[termNumber]);
promise.then(callShrinkGrow);
}
callShrinkGrow();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<span id="el"></span>
关于javascript - 按字符写入/删除文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59519165/