Как извлечь текст из тега html при помощи js?

Рейтинг: -2Ответов: 2Опубликовано: 22.02.2023

Вот html код:

<ul id="btn-list" class="list-catalog list-catalog-sorting">
    <li id="text-list" class="text-list">Дешевле - Дороже
        <ul data-num="0" id="hidden-list" class="choice-sorting">
            <li class="text-choise-sorting">Дешевле - Дороже</li>
            <li class="text-choise-sorting">Дороже - Дешевле</li>
            <li class="text-choise-sorting">По релевантности</li>
        </ul>
    </li>
    <span class="arrow-icon"></span>
</ul>

Мне нужно достать текст только "Дешевле - Дороже", то что первое. Помогите пожалуйста!

Ответы

▲ 3

Получить содержимое текстового узла элемента можно несколькими способами:

  • childNodes : Самое очевидное решение - получить коллекцию всех узлов и выбрать необходимый по его индексу или, для текущего вопроса, с помощью firstChild.

  • cloneNode : Чтобы не "дёргать" реальный DOM, можно клонировать узел и работать уже с копией. Суть способа такова: клонируем элемент, удаляем в нём все (или только конкретные) лишние элементы, найденные querySelectorAll или другими методами. В итоге останется только текстовое содержимое.

    Такое решение верно для текущего вопроса, но если текстовых узлов будет больше, то вернётся и их содержимое тоже.

  • xPath : Очень мощное средство для доступа практически к любому узлу (узлам), но редко используется, в силу заблуждения, что предназначен данный интерфейс исключительно для работы с XML.

    Описание синтаксиса и принципов работы xPath выходит за рамки ответа на текущий вопрос, поэтому рекомендуется к самостоятельному изучению.

  • TreeWolker : Ещё один инструмент для обхода узлов. Чаще всего используется для DOM больших объёмов.

Хочу заметить, что примеры здесь сильно упрощены (например, отсутствуют дополнительные проверки на существование узла):

// Получение из коллекции узлов по индексу
let childs = document.querySelector('#text-list').childNodes;
console.log('childs[0]:\t', childs[0].textContent.trim());
// Получение первого узла в элементе
let child = document.querySelector('#text-list').firstChild;
console.log('firstChild:\t', child.textContent.trim());

// Получение узла с помощью xPath
let xPath = document.evaluate('//*[@id="text-list"]/text()', document, null, XPathResult.STRING_TYPE, null);
console.log('xPath:\t\t', xPath.stringValue.trim());

// Клонирование узла и удаление всех лишних элементов
let clones = document.querySelector('#text-list').cloneNode(true);
clones.querySelectorAll('*').forEach(el => el.remove());
console.log('clones:\t\t', clones.textContent.trim());
// Клонирование узла и удаление конкретного лишнего элемента
let clone = document.querySelector('#text-list').cloneNode(true);
clone.querySelector('#hidden-list').remove();
console.log('clone:\t\t', clone.textContent.trim());

// Получение первого узла из коллекции текстовых узлов полученных при обходе
let walker = document.createTreeWalker(document.querySelector('#text-list'), NodeFilter.SHOW_TEXT).firstChild();
console.log('walker:\t\t', walker.textContent.trim());
<ul id="btn-list" class="list-catalog list-catalog-sorting">
  <li id="text-list" class="text-list">Исчо дишевли - Исчо дарожи
    <ul data-num="0" id="hidden-list" class="choice-sorting">
      <li class="text-choise-sorting">Дешевле - Дороже</li>
      <li class="text-choise-sorting">Дороже - Дешевле</li>
      <li class="text-choise-sorting">По релевантности</li>
    </ul>
  </li>
  <span class="arrow-icon"></span>
</ul>

▲ 1

У искомого вами элемента нет уникального селектора, поэтому невозможно сделать какой-то универсальный запрос. Однако, если вы заранее знаете, что искомый элемент всегда первый в списке (и ранее на странице нигде не встречается), то можете просто взять первое совпадение в querySelector:

let value = document.querySelector('#hidden-list>.text-choise-sorting').innerText

Либо воспользоваться псевдоклассами first-child / nth-child для уточнения запроса, если таких элементов на странице несколько

let values = Array.from(
   document.querySelectorAll('#hidden-list>.text-choise-sorting:first-child')
).map(elem => elem.innerText)