Анимированное меню HTML
Требуется, чтобы при наведении мыши на каждый пункт меню буквы в нём слева направо постепенно заменялись на заглавные. А когда мышь уходит с пункта, так же постепенно заменялись строчными. Я придумал только как сделать это через массив:
<body>
<div class="menu">
<ul>
<li><a id="menuone" href="https://google.com/">home</a></li>
<li><a id="menuone1" href="https://microsoft.com/ru-ru">about</a></li>
<li><a id="menuone2" href="https://ru.stackoverflow.com/">test</a></li>
</ul>
<script type="text/javascript">
let menus = document.getElementById('menuone');
let mass = ['home', 'Home', 'HOme', 'HOMe', 'HOME'];
let b = 0,
startn, startm, isMouseHover = false;
menus.addEventListener("mouseover", function(event) {
isMouseHover = true;
clearInterval(startm);
b = b + 1;
if (b == mass.length) {
b = 4;
}
event.target.textContent = mass[b];
startn = setInterval(ssp, 1000 / 5);
}, false);
function ssp() {
b = b + 1;
if (b >= mass.length) {
b = 4;
}
menus.innerHTML = mass[b];
}
menus.addEventListener("mouseleave", function(event) {
isMouseHover = false;
clearInterval(startn);
b = b - 1;
if (b <= 0) {
b = 0;
clearInterval(startm);
}
event.target.textContent = mass[b];
startm = setInterval(ssm, 1000 / 5);
}, false);
function ssm() {
b = b - 1;
if (b <= 0) {
b = 0;
}
menus.innerHTML = mass[b];
}
</script>
</div>
</body>
Но такой способ не подходит. Как можно реализовать такое меню иначе? Заранее благодарю.
Ответы (2 шт):
Автор решения: Igor
→ Ссылка
.menu ul li a {
font-size: 24pt;
}
<body>
<div class="menu">
<ul>
<li><a id="menuone" href="https://google.com/">home, sweet home</a></li>
<li><a id="menuone1" href="https://microsoft.com/ru-ru">about apples</a></li>
<li><a id="menuone2" href="https://ru.stackoverflow.com/">the walrus and the carpenter</a></li>
</ul>
<script type="text/javascript">
let menus = document.querySelectorAll('.menu ul li a');
menus.forEach(el => el.addEventListener("mouseover", function(event) {
clearInterval(event.target.startMore);
clearInterval(event.target.startLess);
event.target.startMore = setInterval(moreUpper, 1000 / 5, event.target);
}, false));
function moreUpper(el) {
let text = el.textContent;
let upper = text.toUpperCase();
if (text == upper) {
clearInterval(el.startMore);
return;
}
text = text.split('');
upper = upper.split('');
for (let i = 0; i < text.length; i++) {
if (text[i] != upper[i]) {
text[i] = upper[i];
el.textContent = text.join('');
return;
}
}
}
menus.forEach(el => el.addEventListener("mouseleave", function(event) {
clearInterval(event.target.startMore);
clearInterval(event.target.startLess);
event.target.startLess = setInterval(lessUpper, 1000 / 5, event.target);
}, false));
function lessUpper(el) {
let text = el.textContent;
let lower = text.toLowerCase();
if (text == lower) {
clearInterval(el.startLess);
return;
}
text = text.split('');
lower = lower.split('');
for (let i = text.length - 1; i >= 0; i--) {
if (text[i] != lower[i]) {
text[i] = lower[i];
el.textContent = text.join('');
return;
}
}
}
</script>
</div>
</body>
Автор решения: De.Minov
→ Ссылка
Вариант на CSS, правда в одну сторону.
let links = document.querySelectorAll('#nav a'),
delay = 100;
[...links].map(e => {
let split = e.innerText.split(''),
html = '';
split.map((e, i) => {
html += `<span style="animation-delay: ${delay * i}ms;">${e}</span>`;
});
e.innerHTML = html;
});
#nav a {
text-decoration: none;
font-size: 20px;
}
#nav a:hover > span {
text-transform: lowercase;
animation: toUpper .1s linear forwards;
}
@keyframes toUpper {
from {text-transform: lowercase;}
to {text-transform: uppercase;}
}
<ul id="nav">
<li><a href="#">home</a></li>
<li><a href="#">about</a></li>
<li><a href="#">test</a></li>
</ul>