Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   как создать новостную ленту (https://javascript.ru/forum/dom-window/78705-kak-sozdat-novostnuyu-lentu.html)

misha.korolcov 23.10.2019 13:17

как создать новостную ленту
 
Доброе время суток подскажите как создать такую ленту под банером вот пример https://www.globeswiss.com/it-IT/home/ ато я еще никогда не делал такое же зарание спасибо

рони 23.10.2019 14:21

misha.korolcov,
https://javascript.ru/forum/events/7...tml#post513769

misha.korolcov 23.10.2019 15:33

спс

misha.korolcov 23.10.2019 15:35

пробовал перенести у себя на строку не не получается не понимаю где я делаю что-то не так в хтмл мой пример и два других где виходит https://github.com/mishakorolcov1/2

Malleys 23.10.2019 15:42

misha.korolcov, вас интересует отображение только текста, то вы можете использовать мой пример, который вам показал рони, возможности по его стилизации безграничны! Однако если вас интересует бегущая строка (или новостная лента) в которой бы в качестве передвижного элемента использовался любой HTML, возникает интересный вопрос!

Как отобразить содержимое элемента так, чтобы конец содержимого соединялся с началом его, как это происходит в бегущей строке с текстом?

Можно расширить тот элемент, чтобы он работал с любым содержимым!

<text-display>Hello!</text-display>
<text-display>
	<p> Пример ленты с ссылкой:
		<a href="https://javascript.ru/forum">форум на тему JavaScript</a>
		А вообще может быть <em>любой</em> <span style="color: red;">HTML</span>
	</p>
</text-display>
<text-display>
	<img src="https://picsum.photos/300/100?1">
	<img src="https://picsum.photos/300/100?2">
	<img src="https://picsum.photos/300/100?3">
	<img src="https://picsum.photos/300/100?4">
	<img src="https://picsum.photos/300/100?5">
	<img src="https://picsum.photos/300/100?6">
	<img src="https://picsum.photos/300/100?7">
	<img src="https://picsum.photos/300/100?8">
	<img src="https://picsum.photos/300/100?9">
</text-display>

<style>

text-display {
	background: linear-gradient(to bottom, #333, black);
	background-color: #111;
	color: white;
	font: 900 1em / 1.5 monospace, system-ui;
	border-radius: 0.2em;
	white-space: nowrap;
	margin: 0.2em 0;
}

</style>

<script>

class TextDisplay extends HTMLElement {
	constructor() {
		super();

		const shadow = this.attachShadow({ mode: "closed" });
		const document = shadow.ownerDocument;
		const firstElement = document.createElement("div");
		const secondElement = document.createElement("div");
		const slot = document.createElement("slot");
		const observer = new MutationObserver(mutationHandler);

		shadow.innerHTML = `<style>
			:host {
				display: flex;
				overflow: hidden;
			}
			:host > div {
				min-width: 100%;
				will-change: transform;
				animation: text-display var(--text-display-duration, 15s) linear infinite;
				animation-direction: inherit;
				display: flex;
				flex: 1 0 auto;
				text-align: center;
			}
			:lang(ar), :lang(he) {
				animation-direction: reverse;
			}
			@keyframes text-display {
				to {
					transform: translateX(-100%);
				}
			}
		</style>`;

		firstElement.append(slot);
		shadow.append(firstElement, secondElement);
		mutationHandler();

		observer.observe(this, {
			subtree: true,
			characterData: true,
			attributes: true,
			childList: true
		});

		function mutationHandler() {
			secondElement.textContent = "";

			for(const assignedNode of slot.assignedNodes())
				secondElement.append(assignedNode.cloneNode(true));
		}
	}
}

customElements.define("text-display", TextDisplay);

</script>

Malleys 23.10.2019 15:48

Цитата:

Сообщение от misha.korolcov
пробовал перенести у себя на строку не не получается

Вы что-то не то делаете! Если только текст, то так...
<text-display text="Hello world!"></text-display>

<style>

text-display {
	background: linear-gradient(to bottom, #333, black);
	background-color: #111;
	color: white;
	font: 900 1em / 1.5 monospace, system-ui;
	display: flex;
	overflow: hidden;
	white-space: nowrap;
}

text-display::before, text-display::after {
	content: attr(text) "\a0";
	min-width: 100%;
	will-change: transform;
	animation: text-display 15s linear infinite;
	animation-direction: inherit;
	flex: 1 0 auto;
	text-align: center;
}

:lang(ar), :lang(he) {
	animation-direction: reverse;
}

@keyframes text-display {
	to {
		transform: translateX(-100%);
	}
}

</style>


Если нужно отображать HTML-содержимое в бегущей строке, то смотрите моё сообщение выше!

misha.korolcov 23.10.2019 16:03

спс огромной очень помогли , если б мог отблагодарил , ато целый день сижу над этим ))) тяжело жить джуну

рони 23.10.2019 16:30

Malleys,
пост #5, можно узнать как это работает?
что такое slot, откуда там элементы, зачем нужен observer?

Malleys 23.10.2019 17:57

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

рони 23.10.2019 18:18

Malleys,
обьяснение достаточное, спасибо.


Цитата:

Сообщение от Malleys
Писатель плагинов jQuery создал бы из первоначальной разметки такую...

пробовал, не смог добится "плавности" перехода(с вашим примером всё в порядке!), видимо css недостаточно знаю. :)


Часовой пояс GMT +3, время: 02:50.