【问题标题】:JS,CSS) get letters from String and make to fall down each letters smoothly(NO JQUERYJS,CSS)从字符串中获取字母并使每个字母顺利落下(NO JQUERY
【发布时间】:2018-10-31 21:30:46
【问题描述】:

您好,我的网站需要一些有趣的文字动画。

例如掉落的字母。

如果我使用 Word 'Stackoverflow' ,

第一个字母 (S) 会掉下来,然后当第一个字母完成时

第二个字母 (t) 会掉下来,在第三个 (a) 之后...

重复直到最后一个字母掉下来。

下面的代码/jsfiddle 无法按预期工作。

这是我的代码:

var textDOM = document.querySelector('#home p');
function appendLetters(target,text,index){
    if(index<text.length){
        textDOM.innerHTML+='<span>'+text[index++]+'</span>';

        setTimeout(function(){
            textDOM.lastChild.classList.add('index-'+index);
            appendLetters(target,text,index)
        },1000);

    }
}

(function(){
    console.log(appendLetters);
    appendLetters('#home p', 'a simple site made by an web developer',0);
}())

css:

#home p span{
position:relative;
top:-60px;
/*animation:fallLetters 0.2s;*/
transition: top 0.8s linear;
}
#home p span[class^='index-']{
    top:0px;
}

因为 span 标签的转换延迟是 0.8 秒,所以“完全”更改它们的 css 顶部值应该需要 800 毫秒。

但是使用我的代码,除了最后一个之外的所有字母都不想顺利掉下来。不知道为什么。

http://jsfiddle.net/1fcgv0ta/

您只看到最后一个顺利落下,但所有字母都应该顺利落下。如何在没有 JQUERY 的情况下修复我的代码?

我的项目中没有 JQuery 的空间。

【问题讨论】:

    标签: javascript css transition


    【解决方案1】:

    问题的原因完全是因为您通过使用+= 附加到innerHTML 属性来更新DOM。实际上,我之前已经读过关于这种被劝阻的文章,但是直到在这里分析您的代码之前,我才真正意识到为什么! (原因是我倾向于总是使用 jQuery 来处理直接的 DOM 操作任务,所以对 vanilla DOM API 不太熟悉 - 当然,这与答案无关!)

    不管怎样,说:

    node.innerHTML += myHTMLString;
    

    当然等价于:

    node.innerHTML = node.innerHTML + myHTMLString;
    

    但是用手写的方式更清楚地表明你实际上并没有真正“添加”到innerHTML。您只是用全新的 HTML 内容替换它 - “恰好”是添加了新元素的原始内容。

    为什么这很重要?这很重要,因为您使用的是 CSS 过渡。只有当您的 &lt;span&gt; 元素之一添加了 index-* 类之一时,您想要的“下降”效果才会发生。 [旁注,没有理由不为此只使用一个类。] 现在,您当然要在代码中添加这个类 - 但紧接着,您再次调用 appendLetters,正如我刚刚指出的那样, 清除textDOM 的全部内容并用新内容替换。结果,转换实际上并没有发生,因为没有什么可以转换的 - &lt;span class="index-1"&gt;(例如)刚刚从无处出现,其 CSS top 值为 0px。是的,它也有一个 transition 属性,但是由于该元素实际上之前并不存在,因此没有什么可以从 过渡,所以它“只是出现”在你想要成为它的最终位置。

    这也告诉你为什么它为最后一个字母(e)工作。尽管之后调用了 appendLetters,但 if 检查失败,因此您无需更新 DOM - 因此旧的 DOM 不会被销毁并被新的 DOM 替换,并且转换按计划运行。

    唷 - 我使用的时间比我想要的要长得多,但我希望您能欣赏(希望)清晰的解释。

    我相信您会意识到,解决方法是更新 DOM,将新元素 追加 到它,而不是像您正在做的那样销毁然后重新创建至今。因此,而不是违规行:

    textDOM.innerHTML+='<span>'+text[index++]+'</span>';
    

    改为这样做:

    var newSpan = document.createElement('span');
    newSpan.innerHTML = text[index++];
    textDOM.appendChild(newSpan);
    

    希望这能解决您的问题 - 如果确实如此并且您对解释表示赞赏,请给我投票:)

    【讨论】:

    • 感谢您的精彩解释。效果很好
    【解决方案2】:

    我不确定这是否是一个不错的解决方案,但通过在 setTimeout 函数中创建另一个 setTimeout 函数并在嵌套的 setTimeout 函数中调用 appendLetters 来解决。

            setTimeout(function(){
                textDOM.lastChild.classList.add('index-'+index);
                    setTimeout(function(){
                        appendLetters(target,text,index)
                    },400);
            },200);
    

    不知道为什么会这样修复,但这个已修复......

    【讨论】:

    • 这个解决方案对我不起作用。 (无论如何,在 Chrome 上 - 没有尝试过其他浏览器,但不明白为什么现代浏览器的行为应该与此不同。) [但我仍然不知道如何修复它或为什么 OP 的代码没有'行不通,我一直在考虑它并尝试一些东西,断断续续,很长一段时间!]
    • (其实我想通了,看看我即将发布的答案。不幸的是,这个答案肯定不能解决实际问题)
    猜你喜欢
    • 2018-07-11
    • 2013-06-29
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多