Способ № 1 — Через интерфейс DOMParser
Стандарт DOM Parsing and Serialization — https://www.w3.org/TR/DOM-Parsing/ описывает интерфейс DOMParser, у которого есть метод parseFromString(str, type)
Первым параметром метод принимает строку, которая по сути является полноценной разметкой HTML-страницы.
Вторым параметром метод принимает тип распознавания для будущего документа. Это один из:
- «text/html«
- «text/xml»
- «application/xml»
- «application/xhtml+xml»
- «image/svg+xml»
В случае с созданием HTML-документа, нужно выбрать строковое представление «text/html«.
Пример работы
Есть строка — потенциальный фрагмент будущего документа:
let stroka = '<div><h1>Заголовок</h1><p>Текст1</p><p>Текст2</p><p>Текст3</p><ul><li>Красный</li><li>Синий</li><li>Коричневый</li></ul></div>'

Создаём новый объект DOMParser:
let ndp = new DOMParser()

Вызываем метод синтаксического анализа по строке:
let nDoc = ndp.parseFromString(stroka, "text/html")

На выходе получаем объект документа (document), который в элементе body содержит полную разметку, переданную нами в строке.
Более того, если мы передадим не просто HTML-фрагмент документа, а полную HTML-разметку с доктайпами, комментариями и эштемээлями, то на выходе документ будет также хорошо собран. Это важно!
Способ № 2 — Через HTML-элемент iframe
Мы создаём средствами JavaScript новый объект HTML-элемента iframe.
let nif = document.createElement('iframe');
Мы подсаживаем этот iframe в текущий открытый документ, чтобы наш iframe начал участвовать в рендеринге (визуализации) страницы.
document.body.append(nif);
Для атрибута srcdoc нашего iframe мы устанавливаем значение — нужную нам строку для парсинга в HTML-документ.
nif.srcdoc = stroka;
Далее мы дожидаемся события load для iframe, которое будет свидетельствовать о завершении построения объектной модели документа. Это значит, что можно будет работать по новому документу всеми стандартными методами DOM.
let nDoc; nif.onload = (event)=>{ // Выводим в консоль №1 console.log(nif.contentDocument); // Выводим в консоль №2 console.log(event.target.contentDocument); // ...или... // Сохраняем в перменную №1 nDoc = nif.contentDocument // Сохраняем в перменную №2 nDoc = event.target.contentDocument }

Далее мы получаем новый объект документа. Внимание! Вложенного документа! Не исходного открытого во вкладке браузера, а вложенного в iframe. Только у отрисованного iframe свойство contentDocument будет содержать нужный нам документ. Если iframe не будет отрисован, а просто создан в дереве родительского документа, то свойство contentDocument вернёт null.
Процесс частично описан тут — JavaScript | Как дождаться загрузки iframe?
Дополнительная информация
Существует такое понятие, как «фрагмент документа«. Очень важно отличать его от URI-фрагмента, который обозначается решёткой # и имеет связь с элементом на странице по идентификатору id.
Так вот «фрагмент документа» подробно описан в стандарте DOM, в разделе «5.5. Interface Range«. Также имеется отдельный раздел в стандарте DOM Parsing and Serialization, который там называется «8. Extensions to the Range interface«.
Объекты, реализующие интерфейс Range, называются живыми диапазонами (live ranges).
Как это выглядит на практике? Создадим новый объект Range.
let nRange = new Range()

Вызовем на полученном объекте Range метод createContextualFragment(). Внутрь метода мы передаём нашу строку с HTML-разметкой:
let df = nRange.createContextualFragment(stroka)

По итогу нам возвращается новый объект «документ-фрагмент». Какие плюсы мы получаем?
Мы можем обходить вложенные элементы объекта «документ-фрагмент». Это очень круто т. к. по сути нам может быть не всегда нужен полный объект документа!
Например, методом querySelectorAll() с параметром ‘*’, мы можем получить все объекты элементов, отправленных в первоначальной строке
df.querySelectorAll('*')

Или мы можем отобрать все объекты по типу:
[...df.querySelectorAll('*')].filter(element=>element.nodeName=='P') или [...df.querySelectorAll('*')].filter(element=>element.tagName=='P')

К сожалению удобный для работы метод getElementsByTagName() не работает на объектах «документ-фрагмент»