Показать сообщение отдельно
  #9 (permalink)  
Старый 23.10.2019, 17:57
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Элемент <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 будут происходить нужные изменения, но вам об этом думать не нужно) Вы можете менять атрибуты, добавлять и удалять содержимое как обычно.
Ответить с цитированием