JS, CSS) получают буквы из String и заставляют плавно падать каждую букву (NO JQUERY - PullRequest
0 голосов
/ 01 ноября 2018

Привет, мне нужна забавная текстовая анимация для моего сайта.

Например, падающие буквы.

Если я использую слово «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.

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Причина вашей проблемы полностью в том, что вы обновляете DOM путем добавления к свойству innerHTML, используя +=. Я действительно читал раньше об этом обескураживающем, но никогда не понимал почему, пока не проанализировал ваш код здесь! (Причина в том, что я склонен всегда использовать jQuery для задач прямого манипулирования DOM, поэтому не так хорошо знаком с vanilla DOM API - это, конечно, не имеет значения для ответа!)

Во всяком случае, говоря:

node.innerHTML += myHTMLString;

, конечно, эквивалентно:

node.innerHTML = node.innerHTML + myHTMLString;

Но написание этого от руки проясняет, что вы на самом деле не «добавляете» к innerHTML. Вы просто заменили его новым HTML-контентом, который "просто так" является оригинальным контентом с добавленным новым элементом.

Почему это имеет значение здесь? Это важно, потому что вы используете переходы CSS. Эффект «падения», который вам нужен, произойдет только тогда, когда один из ваших элементов <span> получит один из классов index-*, добавленных к нему. [Примечание: нет причин не использовать только один класс для этого.] Теперь вы, конечно, добавляете этот класс в свой код - но сразу после этого вы снова вызываете appendLetters, что, как я только что указал , очищает все содержимое textDOM и заменяет его новым содержимым. В результате, на самом деле переход не происходит, потому что переходить не из чего - например, <span class="index-1"> (например) только что появился из ниоткуда, и имеет значение CSS top 0px. Да, у него тоже есть свойство transition, но поскольку элемент раньше фактически не существовал, нет ничего для перехода из , поэтому он "просто появляется" в том месте, где вы хотели бы быть в его окончательном положении .

Это также говорит вам, почему работал для последнего письма (e). Хотя впоследствии вызывается appendLetters, проверка if завершается неудачно, поэтому вы не обновляете DOM, поэтому старый DOM не разрушается и не заменяется новым, а переходные функции выполняются, как и планировалось.

Фу - Я продержался один дольше, чем хотел, но я надеюсь, что вы оцените (надеюсь) четкое объяснение.

Исправление, как я уверен, вы уже поняли, состоит в том, чтобы обновлять DOM таким образом, чтобы добавлял новый элемент к нему, вместо того, чтобы уничтожать, а затем воссоздавать, как вы это делаете. далеко. Так что вместо обидной строки:

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

сделать это вместо:

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

Надеюсь, это решит вашу проблему - если это произойдет, и вы цените объяснение, пожалуйста, дайте мне голос :):

0 голосов
/ 01 ноября 2018

Я не уверен, что это хорошее решение, но исправлено путем создания другой функции setTimeout в функции setTimeout и вызова appendLetters во вложенной функции setTimeout.

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

Не уверен, почему это исправлено, но исправлено ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...