Я пытаюсь создать выделение (да, я сначала сделал МНОГО поиска по этой теме), используя анимированный text-indent
.Я предпочитаю это решение другим, которые я пробовал, например, использовать перевод на 100%, что приводит к утечке текста за границы моего выделения.
Я пытался следовать этому примеру здесь: https://www.jonathan -petitcolas.com / 2013/05/06 / simulate-marquee-tag-in-css-and-javascript.html
... которую я немного обновил, выполняяэто в TypeScript с использованием обновлений API (appendRule
вместо insertRule
) и отбрасыванием опасений по поводу поддержки старого браузера.
Проблема в том, что анимация перезапускается с использованием старых правил ключевых кадров - шаг, описанныйкомментарий «переназначить анимацию (чтобы она запускалась)» не работает.
Я посмотрел, что происходит в отладчике, и правила определенно меняются - старые правила удалены,добавлены новые правила.Но как будто старые правила где-то кешируются, и они не очищаются.
Вот мой текущий CSS:
#marquee {
position: fixed;
left: 0;
right: 170px;
bottom: 0;
background-color: midnightblue;
font-size: 14px;
padding: 2px 1em;
overflow: hidden;
white-space: nowrap;
animation: none;
}
#marquee:hover {
animation-play-state: paused;
}
@keyframes marquee-0 {
0% {
text-indent: 450px;
}
100% {
text-indent: -500px;
}
}
И соответствующий раздел моего TypeScript:
function updateMarqueeAnimation() {
const marqueeRule = getKeyframesRule('marquee-0');
if (!marqueeRule)
return;
marquee.css('animation', 'unset');
const element = marquee[0];
const textWidth = getTextWidth(marquee.text(), element);
const padding = Number(window.getComputedStyle(element).getPropertyValue('padding-left').replace('px', '')) +
Number(window.getComputedStyle(element).getPropertyValue('padding-right').replace('px', ''));
const offsetWidth = element.offsetWidth;
if (textWidth + padding <= offsetWidth)
return;
marqueeRule.deleteRule('0%');
marqueeRule.deleteRule('100%');
marqueeRule.appendRule('0% { text-indent: ' + offsetWidth + 'px; }');
marqueeRule.appendRule('100% { text-indent: -' + textWidth + 'px; }');
setTimeout(() => marquee.css('animation', 'marquee-0 15s linear infinite'));
}
До сих пор я пробовал несколько хитростей, чтобы обойти эту проблему, включая такие вещи, как клонирование элемента выделения и замена его собственным клоном, и ничего из этого не помогло - анимация продолжаетработать так, как если бы действовали исходные значения таблицы стилей, поэтому прокрутка области не адаптируется к разной ширине текста.
Следующее, что я, вероятно, попробую, - это динамическое создание новых объектов ключевых кадров вместо редактированияправила внутри существующего объекта ключевых кадров, но это грязное решение, которого я бы предпочел избегать, если у кого-то есть лучшее решение.