Элемент <text-display> прокручивает своё содержимое, как бегущая строка. Время, за которое пройдёт один цикл бегущей строки задаётся при помощи CSS-свойства --text-display-duration, по умолчанию за 15 сек.
Сообщение от рони
|
пост #5, можно узнать как это работает?
|
Технические детали, которые нужны рони. Если мы захотим прокручивать содержимое <text-display> как есть, то мы столкнёмся со следующей проблемой... Текст вообще нельзя сдвинуть при помощи CSS, а если мы его обернём в <div> (чем страдают многие jQuery плагины), то мы столкнёмся с тем, что содержимое больше не является непосредственным потомком элемента <text-display>, что может сломать стили, а меня, как разработчика класса TextDisplay, свяжет по рукам тот факт, что я не смогу улучшать его разметку, поскольку те, кто используют <text-display> могут полагаться на то, что сгенерированное содержимое не будет меняться со временем.
Чтобы избежать таких проблем, был представлен теневой DOM, который позволяет фактически добавлять элементы между элементом и его потомками не меняя существующую структуру DOM.
Например, рассмотрим, как такую разметку...
<text-display>
<img src="https://picsum.photos/3000/100">
</text-display>
превратить в бегущую строку ничего в ней не меняя.
Писатель плагинов jQuery создал бы из первоначальной разметки такую...
<text-display>
<div>
<img src="https://picsum.photos/3000/100">
</div>
<div>
<img src="https://picsum.photos/3000/100">
</div>
</text-display>
... и уже дальше бы с ней работал. Правда разработчики использующие такой плагин уже бы не смогли просто так менять содержимое <text-display> при помощи DOM API, поскольку это бы поломало работу бегущей строки! Поэтому писателю плагина пришлось бы предоставить дополнительные методы для изменения и получения первоначального содержимого. Как видите, писатель плагина jQuery предлагает несовместимый с DOM API код, который бы ещё потребовал дополнительной инициализации!
Разработчики же теневого DOM предлагают метод attachShadow, который позволяет связать теневой DOM c вашим элементом в лицевом DOM, ничего не переставляя в иерархии элементов в лицевом DOM!
<text-display>
<!-- #shadow-root -->
<img src="https://picsum.photos/3000/100">
</text-display>
И уже дальше работать с теневым DOM, который изолирован от остальных элементов в иерархии лицевого DOM. Например, для работы <text-display> я сделал программно в примере выше такой теневой DOM...
<!-- #shadow-root -->
<style>/* стили смотрите в работающем примере выше */</style>
<div>
<slot></slot>
</div>
<div></div>
Сообщение от рони
|
что такое slot, откуда там элементы
|
Элемент <slot> представляет потомков <text-display> из лицевого DOM, но не содержит их. Визуально это выглядит так, как будто элементы вставлены в <slot>.
Мне нужно было для примера, чтобы потомки <text-display> представленные при помощи <slot> также отображались во втором <div>.
Сообщение от рони
|
зачем нужен observer?
|
Поэтому я отслеживаю любые изменения в <text-display> при помощи MutationObserver. (а он содержит только картинку, изменения в теневом DOM не учитываются поскольку к нему нет доступа из лицевого DOM)
Когда изменения в <text-display> происходят, то потомки <text-display> представленные при помощи <slot> копируются во второй <div> (метод assignedNodes у класса HTMLSlotElement)
Вот как! Разметка по прежнему осталась...
<text-display>
<img src="https://picsum.photos/3000/100">
</text-display>
Вы можете её менять при помощи DOM API или того же jQuery, никаких дополнительных ограничении и методов для работы с элементом нет! (в теневом DOM будут происходить нужные изменения, но вам об этом думать не нужно) Вы можете менять атрибуты, добавлять и удалять содержимое как обычно.