Форум программистов, компьютерный форум, киберфорум
JavaScript
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/11: Рейтинг темы: голосов - 11, средняя оценка - 5.00
9 / 9 / 4
Регистрация: 19.05.2013
Сообщений: 63

Симуляция печатания текста

09.10.2017, 03:58. Показов 2323. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день! Была задачка написать скрипт симуляции набора текста в браузере.

Вернее заказчик попросил. Хотел спросить мнение у вас касательно его реализации. Скрипт работает! Ну так как я самоучка, мне не у кого спросить касательно того правильно ли написан код и не от кого выслушать замечания. Если вам не сложно, прокомментируйте пожалуйста мою работу.

Вот HTML разметка.
HTML5
1
2
3
4
5
6
    <div id="typeSB">
        <p class="typeSB_start">Мы делаем: </p>
        <p>уникальный дизайн.</p>
        <p>современные сайты.</p>
        <p>настройку SEO.</p>
    </div>
Вот JS код
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
window.onload = function(){
            var div = document.getElementById("typeSB");
            if(div){
                var p = div.childNodes;
                var textArr = [];
                var textArrRel = [];
                var count = 0;
                for (var i = 0; i < p.length; i++){
                    if(p[i].nodeType == 1){
                        if(p[i].className == "typeSB_start"){
                            p[i].style.display = 'inline-block';
                            continue;
                        }
                        if(p[i].className == "typeSB_start_static"){
                            p[i].style.display = 'block';
                            continue;
                        }
                        textArr.push(p[i].textContent);
                        textArrRel.push(p[i]);
                        p[i].textContent = "";
                        p[i].style.display = 'inline-block';
                    }
                }
                setTimeout(function(){
                    printText(textArr[count], textArrRel[0]);
                }, 1000);
            }
            function printText(text, node){
                function printTextStart(){
                    var i = node.textContent.length;
                    if(i < text.length){
                        node.textContent += text[i];
                        setTimeout(function(){
                            printTextStart();
                        },100);
                    }
                    else{
                        setTimeout(function(){
                            printTextEnd();
                        },1000);
                    }
                }
 
                function printTextEnd(){
                    var i = node.textContent.length;
                    if(i != 0){
                        node.textContent = node.textContent.slice(0, -1);
                        setTimeout(function(){
                            printTextEnd();
                        },30);
                    }
                    else{
                        if(count >= textArrRel.length-1) count = 0;
                        else count++;
                        setTimeout(function(){
                            printText(textArr[count], textArrRel[0]);
                        },900);
                    }
                }
 
                setTimeout(function(){
                    printTextStart();
                }, 300);
            }
        };
Заранее спасибо!

Добавлено через 1 час 32 минуты
Ну и еще вопрос...
Как мне сделать чтоб вот этот скрипт работал на несколько элементов.

Допустим я выбрал нужный мне Div путем выбора класса getElementsByClassName(). Я получил в массив выборку всех классов. Путем цикла for не получится.

Бошка расплавиться если это все делать путем вызова рекурсивных функций. Да и таймер постоянно сбиваться будет, так как насколько я понял, он ОДИН. Как это все правильно сделать?

Чтоб на каждый класс со вложенными тегами p применялось это?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
09.10.2017, 03:58
Ответы с готовыми решениями:

Скрипт печатания
Поставил скрипт печатания. Мне не нужен курсор, но не могу его убрать Ссылка на хостинг - https://bit.ly/2KkWv6W ...

Анимация печатания текста в TextView
Приветствую всех. Сразу покажу, чего хочу добиться (черные косяки вокруг букв в планы не входят :D). Есть String, есть...

Написать программу печатания текста по буквам
Ребята..помогите.. как мне сделать так, чтобы текст печатался по буквам в graphABC, как например в разных квест играх во время диалогов,...

9
Эксперт JS
2463 / 1769 / 625
Регистрация: 11.07.2016
Сообщений: 4,067
09.10.2017, 09:52
Цитата Сообщение от Mostick Посмотреть сообщение
Путем цикла for не получится.
Почему не получится?
0
9 / 9 / 4
Регистрация: 19.05.2013
Сообщений: 63
09.10.2017, 11:18  [ТС]
Можете подсказать примерную логику?

Добавлено через 1 час 0 минут
Если использовать цикл for, каждая итерация цикла происходит моментально. И таймер каждой итерации проставится один и тот же)

Конечто можно попробовать создать что то типа
JavaScript
1
for(var i = 0, var timer = 300; i < arr.length; i++, timer += timer)
и переменную timer подставлять нужной функции. Но по моему это порнография...
0
Эксперт JS
2463 / 1769 / 625
Регистрация: 11.07.2016
Сообщений: 4,067
09.10.2017, 11:24
Просто передайте в функцию-коллбек таймеров разные аргументы на разных итерациях цикла.
0
388 / 275 / 76
Регистрация: 19.09.2011
Сообщений: 828
11.10.2017, 15:58
JavaScript
1
2
3
4
5
6
7
8
9
10
11
var str = "Делаю красива чекай";
var result = "";
 
(function(chars) {
    var char = chars.shift();
    result += char;
    console.log(result);
    if (chars.length) {
        setTimeout(arguments.callee, Math.random() * 300 + 50, chars);
    }
})(str.split(""));
недавно делал свой вариант
Эффект печатающегося текста
0
9 / 9 / 4
Регистрация: 19.05.2013
Сообщений: 63
11.10.2017, 20:32  [ТС]
Спасибо! Я тоже недавно улучшил свой скрипт. Теперь поддерживает множество элементов на странице. Хоть 1000.

Все равно не уверен в правильном написании кода. Так же не уверен в его оптимизации. А еще бошка болит касательно того, как сделать это все добро с вложенными тегами.

Например, мой скрипт берет тэг P он вложен в Div с классом sb-type-default. В тэге P к примеру есть теги <a> или <span> или <strong>. Как правильно сделать чтоб это все красиво отрисовывалось?.

Вот мой код кому интересно:

HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="sb-type-default">
    <p class="sb-type-start">Мы делаем: </p>
    <p>Привет Димон, как дела?</p>
    <p>Привет, у меня нормально! Ты как?</p>
    <p>Тож хорошо :)</p>
</div>
 
<div class="sb-type-pointer">
    <p class="sb-type-start">Мы делаем: </p>
    <p>Привет Саня, как дела?</p>
    <p>Привет, у меня нормально! Ты как?</p>
    <p>Тож хорошо :)</p>
</div>
А вот JS
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
var divDefaul;
var divPointer;
var textArr = [];
var textArrText = [];
 
window.onload = function(){
    divDefaul = document.getElementsByClassName("sb-type-default");
    divPointer = document.getElementsByClassName("sb-type-pointer");
    defineDivs(divDefaul);
    defineDivs(divPointer);
    printText(textArr, textArrText);
};
 
function defineDivs(div){
    if(div.length){
        for(var i = 0; i < div.length; i++){
            defineTextArrs(div[i].getElementsByTagName("p"));
        }
    }
}
 
 
function defineTextArrs(node){
    var tempArr = [];
    var tempArrText = [];
    var tempLength = node.length - 1;
    for (var j = node.length - 1; j >= 0; j--){
        if(node[j].className == "sb-type-start"){
            node[j].style.display = 'inline-block';
        }
        else if(node[j].className == "sb-type-start-static"){
            node[j].style.display = '';
        }
        else{
            node[j].style.display = 'inline-block';
            if(node[j].parentNode.className == "sb-type-default"){
                node[j].className += ' sb-after-default';
            }
            else if(node[j].parentNode.className == "sb-type-pointer") {
                node[j].className += ' sb-after-pointer';
            }
            tempArrText.push(node[j].textContent);
            if(j == node.length - 1){
                node[j].textContent = "";
                textArr.push(node[j]);
            }
            else{
                node[j].remove();
            }
        }
    }
    if(!tempArrText.length) return false;
    textArrText.push(tempArrText.reverse());
}
 
 
function printText(node, text){
    for(var i = 0; i < text.length; i++){
        setTimeout(printTextNode, 1000, node[i], text[i], 0);
    }
}
 
function printTextNode(node, text, start){
    var step = start;
    if(step == text.length) step = 0;
    var nodeLength = node.textContent.length;
    node.textContent += text[step][nodeLength];
    if(nodeLength >= text[step].length - 1){
        setTimeout(removeTextNode, 1000, node, text, step);
    }
    else{
        setTimeout(printTextNode, 100, node, text, step);
    }
}
 
function removeTextNode(node, text, start){
    var step = start;
    node.textContent = node.textContent.slice(0, -1);
    if(node.textContent.length <= 0){
        setTimeout(printTextNode, 1000, node, text, ++step);
    }
    else{
        setTimeout(removeTextNode, 30, node, text, step);
    }
}


Очень прошу прокомментировать и поставить оценку. Хочу знать насколько КРИВЫМ является данный код по 10-бальной шкале) Заранее спасибо.

Ну и еще сейчас смотрю в сторону ООП. Я понимаю что ООП - объекто ориентированное программирование построенное на объектах и методах. Я хочу понять как писать в таком стиле, но не хватает немного понимания касательно как это делать правильно.

Я бы мог создать обьект, дать ему свойства и методы и все делать при помощи одного обьекта, например PrintedText. В нем бы был массив всех строк, таймер, методы... Ну есть ли в этом СМЫСЛ? Или ООП удобен только тогда, когда проект огромен?
0
388 / 275 / 76
Регистрация: 19.09.2011
Сообщений: 828
12.10.2017, 13:32
Цитата Сообщение от Mostick Посмотреть сообщение
Все равно не уверен в правильном написании кода.
для начала сделай что бы оно работало https://jsfiddle.net/s6pL0m78/

Цитата Сообщение от Mostick Посмотреть сообщение
JavaScript
1
2
3
4
5
6
7
function defineDivs(div){
    if(div.length){
        for(var i = 0; i < div.length; i++){
            defineTextArrs(div[i].getElementsByTagName("p"));
        }
    }
}
JavaScript
1
2
3
4
if (!div.length) {
    return;
}
for...
for (var j = node.length - 1; j >= 0; j--){ // почему тут j

if(node[j].className == "sb-type-start"){ // зачем каждый раз делать node[j] если можно сделать var asd = node[j]

if(bool){
//
} else if (asd) {
//
} else {
//
}


Цитата Сообщение от Mostick Посмотреть сообщение
Ну и еще сейчас смотрю в сторону ООП. Я понимаю что ООП - объекто ориентированное программирование построенное на объектах и методах. Я хочу понять как писать в таком стиле, но не хватает немного понимания касательно как это делать правильно.
взять вектор: у него есть два свойства x и y.

как это лучше написать?

"var vec = {x: 0, y: 0};" или "var vec = new Vec2(0, 0);"?
допустим он используется только для одной цели: отрисовать точку на экране. тогда очевидный выбор первого варианта, ну потому что он самый простой. но потом тебе говорят что эта точка должна двигаться, и ты пишешь vec.x += speed, vec.y += speed. а потом говорят что движение должно быть по сложным траекториям, и уже нужно не только сложение но и другие операции. вот ты дописываешь функции add(vec1, vec2)//сложение, mul(v1, v2)//умножение, поскольку тебе надоело складывать руками две точки. в итоге ты написал симулятор жидкостей, и у тебя огромная масса логики и всяких математических функций. и все это добро лежит в глобальной области видимости. и когда ты пытаешься соединить свой код с чужим, оно конечно же начинает конфликтовать, у тебя add складывает вектора, у другого человека add стреляет в ногу.
и тогда v1.add(v2) оказывается все же предпочтительнее, чем add(v1, v2).

но если в задании тебе только нужно отрисовать одну точку, зачем тебе делать что то помимо отрисовывания точки? зачем оборачивать точку в класс, если в проекте она больше нигде не используется?

плюсы и минусы того или иного подхода можно очень долго описывать. но работать тебе придется и с тем и с другим, так что можешь попробовать переписать на ооп, если не сильно разбираешься в таком подходе. а как именно писать ооп - в js много способов, например https://learn.javascript.ru/prototypes.
1
9 / 9 / 4
Регистрация: 19.05.2013
Сообщений: 63
12.10.2017, 23:59  [ТС]
Спасибо большое за отзыв! Все вы правильно написали и сказали! Все приму к сведению.

Не согласен только с этим вот

Цитата Сообщение от nubideus Посмотреть сообщение
для начала сделай что бы оно работало https://jsfiddle.net/s6pL0m78/
Оно работает! В самом скрипте есть событие OnLoad, именно на этом событии и построен весь скрипт, дабы было не важно в Body или в Head прописан скрипт. Я все делаю через sublimetext и браузер, никогда сервисами по типу https://jsfiddle.net/ не пользовался.

Если в настройках JavaScript на https://jsfiddle.net/ поставить LoadType - No Wrap in head. То все отлично.

Цитата Сообщение от nubideus Посмотреть сообщение
for (var j = node.length - 1; j >= 0; j--){ // почему тут j
Моя ошибка. Думал что если функция вызвана внутри цикла, где есть переменная i, то эта переменная останется и в функции. Я пока не особо понимаю где глобальные переменные а где локальные....
1
388 / 275 / 76
Регистрация: 19.09.2011
Сообщений: 828
13.10.2017, 01:08
Лучший ответ Сообщение было отмечено Mostick как решение

Решение

Цитата Сообщение от Mostick Посмотреть сообщение
Я пока не особо понимаю где глобальные переменные а где локальные....
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
глобальная
 
(function(){
    var локальная
    без_var_глобальная
    for(без_var_глобальная, var локальная_видимая_во_всей функции, let в_пределах_блока_for;;){
    
    }
    {
        let видимая_только_в_пределах_блока
    }
})()
---
(function() {
    console.log(a)// переменная создается до выполнения тела функции и ошибки не будет. но выведет undefined.
    console.log(c) // error
    console.log(b) // error
    var a = 1;
    let b = 2;
    c = 3;
})()
---
var obj = {d: 1};
 
with(obj) { // with вроде как is deprecated и вообще не рекомендовано к использованию
    d = 2;
}
 
console.log(obj.d) // 2
console.log(d) // error
Цитата Сообщение от Mostick Посмотреть сообщение
Оно работает! В самом скрипте есть событие OnLoad, именно на этом событии и построен весь скрипт, дабы было не важно в Body или в Head прописан скрипт. Я все делаю через sublimetext и браузер, никогда сервисами по типу https://jsfiddle.net/ не пользовался.
да, работает очень мило
1
9 / 9 / 4
Регистрация: 19.05.2013
Сообщений: 63
13.10.2017, 01:29  [ТС]
Спасибо вам за такой подробный ответ!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
13.10.2017, 01:29
Помогаю со студенческими работами здесь

После окончания печатания текста выполнить действие
есть скрипт печатания текста по буквам. не знаю как после того как весь текст напечатан отключить объект.(txt) using UnityEngine; ...

Как программно сменить язык печатания символов
Как программно сменить язык печатания символов на украинский, русский и английский?!

Как кодом задать отступы вместо печатания пробелов с руки
Пишу код напр. sb.AppendLine(&quot;-p=&lt;px:py&gt; - Coordinate of the top-left corner of OW in screen...

Написать программу для печатания таблицы значений функции y ( x ) на заданном отрезке
Написать программу для печатания таблицы значений функции y ( x ) на заданном отрезке с шагом h . Формулы надо переписывать! Редактор...

Глюк печатания и глюк порчи константы
Дамы и господа! Я столкнулся с двумя глюками, которые не нашёл в списке распространённых ошибок. 1) При попытке распечатать массив...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru