Извлечение текста из контента с использованием HTML Slot, HTML Template и Shadow DOM

Извлечение текста из контента с использованием HTML Slot, HTML Template и Shadow DOM

От автора: названия глав в книгах, цитаты, ключевые слова в статье, статистика в отчете — это все типы контента, который может быть выделен и превращен в краткое изложение того, что важно. Например, вы видели, как Business Insider предоставляет ключевые моменты статьи перед тем, как перейти к содержанию?

Это то, что мы собираемся сделать, но мы попробуем извлечь основные моменты непосредственно из статьи, используя Template и Slot HTML, а также Shadow DOM.

Эти три основные спецификации обычно используются как часть веб-компонентов — полнофункциональных модулей пользовательских элементов, предназначенных для повторного использования на веб-страницах. Для нашей задачи не нужно использовать пользовательские элементы, мы можем применить эти три технологии.

Существует более рудиментарный подход к этому. Например, мы могли бы извлечь текст и показать извлеченный текст на странице с помощью некоторого базового скрипта, не используя слот и шаблон. Так зачем их использовать, если мы можем работать с чем-то более знакомым?

Причина в том, что использование этих технологий позволяет нам получить предустановленный код разметки (также, необязательно, стиль или скрипт) для нашего извлеченного текста в HTML. Мы рассмотрим это ниже. Теперь, в качестве очень упрощенного определения технологий, которые мы будем использовать, я бы сказала:

Шаблон представляет собой набор разметки, который может быть использован повторно на странице.

Слот является заполнителем для назначенного элемента со страницы.

Shadow DOM является деревом DOM, которое на самом деле не существует на странице, пока мы не добавим его с помощью скрипта.

Мы рассмотрим их немного подробнее, как только перейдем к кодированию. На данный момент мы собираемся создать статью со списком ключевых моментов из текста ниже. И, как вы, наверное, догадались, эти ключевые моменты извлекаются из текста статьи и компилируются в раздел ключевых моментов.

Ключевые моменты отображаются в виде списка с элементом дизайна между пунктами. Итак, давайте сначала создадим шаблон для этого списка и назначим место для списка.

<article><!-- Содержимое статьи --></article> <!-- Раздел, где будут отображаться выбранные ключевые моменты -->
<section id='keyPointsSection'> <h2>Key Points:</h2> <ul><!-- Здесь будут отображаться выбранные ключевые моменты --></ul>
</section> <!-- Шаблон для списка ключевых моментов -->
<template id='keyPointsTemplate'> <li><slot name='keyPoints'></slot></li> <li style="text-align: center;">&#x2919;&mdash;&#x291a;</li>
</template>

У нас есть семантический section с ul, в котором будет размещаться список ключевых моментов. Затем у нас есть template для элементов списка, который имеет два элемента li: один со <slot> заполнителем для ключевых моментов из статьи, а другой с центрированным элементом дизайна.

Макет произвольный. Что действительно важно, так это место slot, куда будут извлечены ключевые моменты. Все, что внутри template, не будет отображаться на странице, пока мы не добавим его на страницу с помощью скрипта.
Кроме того, разметка внутри template может быть стилизована с использованием встроенных стилей или CSS, заключенного в style:

<template id='keyPointsTemplate'> <li><slot name='keyPoints'></slot></li> <li style="text-align: center;">&#x2919;&mdash;&#x291a;</li> <style> li{/* Стили */} </style>
</template>

Самое интересное! Давайте выберем ключевые моменты из статьи. Обратите внимание на значение атрибута name для slot функции template (keyPoints), потому что нам это нужно.

<article> <h1>Bears</h1> <p>Bears are carnivoran mammals of the family Ursidae. <span><span slot='keyPoints'>They are classified as caniforms, or doglike carnivorans</span></span>. Although only eight species of bears <!-- more content --> and partially in the Southern Hemisphere. <span><span slot='keyPoints'>Bears are found on the continents of North America, South America, Europe, and Asia</span></span>.<!-- more content --></p> <p>While the polar bear is mostly carnivorous, <!-- more content -->. Bears use shelters, such as caves and logs, as their dens; <span><span slot='keyPoints'>Most species occupy their dens during the winter for a long period of hibernation</span></span>, up to 100 days.</p> <!-- Другие абзацы --> </article>

Ключевые моменты обернуты в span, содержащий значение атрибута slot («keyPoints»), соответствующее name в заполнителе slot внутри template. Также обратите внимание, что я добавил еще одну внешнюю оболочку ключевых моментов span.

Причина в том, что имена слотов обычно уникальны и не повторяются, потому что один slot соответствует одному элементу, используя одно имя слота. Если существует более одного элемента с одним и тем же именем слота, заполнитель slot будет последовательно заменен всеми этими элементами, заканчивая последним элементом, являющимся конечным содержимым заполнителя.

Таким образом, если мы сопоставляем этот один slot внутри template со всеми элементами span с одинаковым значением атрибута slot (наши ключевые моменты) в абзаце или всей статьи, мы в конечном итоге получим только последний ключевой момент в абзаце или статье вместо slot.

Это не то, что нам нужно. Нам нужно вывести все ключевые моменты. Итак, мы обертываем ключевые моменты внешним span, чтобы сопоставить каждый из этих отдельных ключевых моментов отдельно со slot. Это станет понятнее, если взглянуть на скрипт, поэтому давайте сделаем это.

const keyPointsTemplate = document.querySelector('#keyPointsTemplate').content;
const keyPointsSection = document.querySelector('#keyPointsSection > ul');
/* Перебираем элементы с атрибутом 'slot' */
document.querySelectorAll('[slot]').forEach((slot)=>{ let span = slot.parentNode.cloneNode(true); span.attachShadow({ mode: 'closed' }).appendChild(keyPointsTemplate.cloneNode(true)); keyPointsSection.appendChild(span);
});

Сначала мы перебираем каждый атрибут span с атрибутом slot и получаем копию его родителя (внешнего span). Обратите внимание, что мы могли бы также перебрать через цикл внешние span, задавая им общее значение class.

Затем внешняя копия присоединяется к теневому дереву (span.attachShadow), составленному из клона содержимого шаблона (keyPointsTemplate.cloneNode(true)).

Это «вложение» приводит к тому, что внутренний элемент slot шаблона списка в теневом дереве поглощает внутреннюю часть span, содержащую имя соответствующего слота, то есть наш ключевой момент. Ключевой момент слота затем добавляется в раздел ключевых моментов в конце страницы (keyPointsSection.appendChild(span)). Это происходит со всеми ключевыми моментами.

Вот на самом деле и все. Мы захватили все ключевые моменты в статье, сделали их копии, а затем поместили копии в шаблон списка, чтобы все ключевые точки были сгруппированы вместе, предоставляя небольшой обзор статьи, похожий на CliffsNotes. Вот это демо еще раз:

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

Автор: Preethi

Источник: https://css-tricks.com/

Редакция: Команда webformyself.