Есть задача. Появления текста в блоке, в произвольной последовательности, по буквам (Например для слова Hello, чтоб буквы появлялись в подобной последовательности eHlol). Тестовый блок
Javascript is an awesome language
Единственное что пришло в голову, это обернуть каждую букву текста в и потом показывать его с рандомный таймаутом. Но сложность обстоит с тэгами. Что с ними можно сделать? Убирать, оборачивать потом снова добавлять? Может быть это реализуется без JS с помощью СSS?
Ответ
Пока другого не придумал. Каждую букву обернуть в span с классом, который ставит visibility: hidden, одновременно запихнув все созданные span'ы в массив. Массив случайно перемешать. И затем по очереди у каждого из массива снимать прячущий класс:
var spans = []
,allTextNodes = getTextNodes( document.getElementById('b-test'))
,i
,timer
;
/**
* recursively get all text nodes as an array for a given element
*/
function getTextNodes(node) {
var childTextNodes = [];
if (!node.hasChildNodes()) return;
var childNodes = node.childNodes;
for (var i = 0; i < childNodes.length; i++) {
if (childNodes[i].nodeType == Node.TEXT_NODE) {
childTextNodes.push(childNodes[i]);
} else if (childNodes[i].nodeType == Node.ELEMENT_NODE) {
Array.prototype.push.apply(childTextNodes, getTextNodes(childNodes[i]));
}
}
return childTextNodes;
}
/**
* given a text node, wrap each character in the
* given tag.
*/
function wrapEachCharacter(textNode, tag, className = '') {
var text = textNode.nodeValue;
var parent = textNode.parentNode;
var characters = text.split('');
var elements = [];
characters.forEach(function(character) {
var element = document.createElement(tag);
element.className = className;
var characterNode = document.createTextNode(character);
element.appendChild(characterNode);
parent.insertBefore(element, textNode);
spans.push(element);
});
parent.removeChild(textNode);
}
allTextNodes.forEach(function(textNode) {
wrapEachCharacter(textNode, 'span', 'h');
});
/**
* Shuffles array in place.
* @param {Array} a items The array containing the items.
*/
function shuffle(a) {
var j, x, i;
for (i = a.length; i; i--) {
j = Math.floor(Math.random() * i);
x = a[i - 1];
a[i - 1] = a[j];
a[j] = x;
}
}
shuffle(spans);
i = spans.length - 1;
function showOne() {
spans[i--].className = "";
if (i < 0) clearInterval(timer);
}
timer = window.setInterval(showOne.bind(this), 100);
span.h{visibility: hidden}
Javascript is an awesome language
Что улучшить: пробелы не надо оборачивать и прятать – только видимые буквы, иначе нарушается видимый «ритм» появления символов.
Ещё недостаток: слова перестают быть целыми словами и могут рваться переносом строки. Выход: оборачивать каждое слово в
Комментариев нет:
Отправить комментарий