【问题标题】:Write/delete text by character按字符写入/删除文本
【发布时间】:2019-12-29 11:55:29
【问题描述】:

我尝试逐个字符地更改任何文本(逐个字符显示文本,逐个字符删除文本并逐个字符显示另一个字符)。

我实际拥有什么?

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); 

好的,由于cmets的一点解释

我有一个元素

&lt;span id=el&gt;text &lt;b&gt;bold&lt;/b&gt;&lt;/span&gt;

在 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.

等等。你能帮我吗?尝试了过去 2 天,多次尝试,没有结果...
谢谢

【问题讨论】:

  • terms 在哪里发挥作用? classes中的各种值的定义是什么?如果您添加更多代码并将其转换为完整的代码 sn-p,将会很有帮助。
  • 请说明你有什么,你想要什么。让你的问题更清楚
  • @Booboo: var terms 在第二行定义。
  • 是的,但是我们不知道cls1 类的定义,对吗?我说的是“值 in classes”。大概这是CSS 风格。
  • 我已经添加了一点解释...更清楚? :-)

标签: javascript jquery substring


【解决方案1】:

这就是我组织代码以缩小和扩大元素的方式。我能做到这一点的唯一明智方法是首先将&amp;lt;&amp;gt; 替换为相应的实体代码&amp;lt;&amp;gt;,这样这些字符就不会被解释为实际标签。这些 4 个字母的实体代码将被删除并作为一个单元添加。通过这种方式,您可以将字符串从右到左一次缩小一个准字符,并且始终保持有效的 HTML。

Promise api(实际上是 jQuery 的 $.Deferred 版本)用于能够以一种确定的方式知道收缩-增长周期(这是一个异步过程)何时完成,然后启动重新开始之前的 2500 毫秒延迟(这是另一个异步过程)。

$(function() {

    function shrink_grow(resolve, term)
    {
        term = term.replace(/</g, '&lt;').replace(/>/g, '&gt;');

        let el = $('#el');
        el.html(term);

        let interval = setInterval(shrinker, 30);

        function shrinker()
        {
            let str = el.html();
            let n = str.length >= 4 && (str.endsWith('&gt;') || str.endsWith(`&lt;`)) ? 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) == '&lt;' || term.substr(str.length + 1, 4) == '&gt;')) {
                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>

【讨论】:

  • 谢谢,我去看看。我所看到的,每个字母更改有 300 毫秒,我需要 300 毫秒来隐藏/显示整个文本。并且您评论了&lt;b&gt; 标签的问题,但您对它们什么都不做......您有什么想法,如何改进它?当然,至少为此 +1。
  • 我将时间间隔改为 30 毫秒。和 &lt;span&gt; 包含 &lt;b&gt; 标记,因此包含 jQuery 选择器。
  • 再一次 :-) 间隔不应该是静态的 30 毫秒,而是动态的(没关系,自己做)...但是显示/隐藏的文本不只是在 &lt;b&gt; 内部,它的文本包括 &lt;b&gt;。请参阅问题,要显示/隐藏的字符串例如 text &lt;b&gt;bold&lt;/b&gt;(包括空格在内的 9 个字符)。
  • 我改变了整个元素的内容(不仅仅是孩子b),所以选择器是$('#el')。内容例如。 text &lt;b&gt;bold&lt;/b&gt;(9个字符,每个字符时间变化300ms / 9 ~ 33ms),或longer text with &lt;i&gt;italic&lt;/i&gt; text.(29个字符,每个字符时间变化300/29ms ~ 10ms)。
  • 您需要将两个选择器$(#el b)(#el) 分配给el2。当您缩小第一个并且文本长度为 0 时,获取第二个选择器 el2.html() 的内容并保存在 text2 并继续 shrinkingel2.html() 直到它的长度变为 0 然后切换到growing。在growing 中,从el2.html() 开始,长度为test2.length,然后切换到el.html(),直到长度为text.length。唯一棘手的一点是每次调用 shrinkinggrowing 您正在使用哪个元素。但你可以弄清楚,我敢肯定。
【解决方案2】:

好的,根据我的理解,你想按字符显示字符串/文本字符。所以我认为这会对你有所帮助。

var str = "Hello World";
var c = "";


var i = 0;
(function loop(){
    if (i++ > str.length-1) return;
    c = c + str[i-1];
    setTimeout(function(){
       $("#charP").text(c);
    loop();
   }, 100);
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<p id="charP"></p>
</div>

【讨论】:

  • 不,首先逐个字符删除文本,然后显示另一个。根据文本长度在 300 毫秒内显示/隐藏。正如我所写的那样,部分文本以粗体显示。
猜你喜欢
  • 1970-01-01
  • 2015-02-17
  • 2013-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多