Поиск HTML-элемента по содержимому текста в JavaScript

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для быстрого поиска элемента по значению innerText, используйте XPath в JavaScript таким образом:

JS
Скопировать код
function getElementByText(text) {
  const xpath = `//node()[normalize-space(text())='${text.trim()}']`;
  return document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

const myElement = getElementByText("Точный текст");
console.log(myElement); // Вот и бережно искомый элемент перед вами!

Замените "Точный текст" на ту строку, которую вы хотите найти. Эта функция проходит через документ с помощью XPath, подобно исполнительной поисковой собаке.

Кинга Идем в IT: пошаговый план для смены профессии

Погрузимся поглубже: понимание XPath и textContent

Прецизионное управление с XPath

Применение XPath в JavaScript допускает точный поиск элементов, которые идентичны указанному тексту. Отметим, что textContent извлекает все текстовые данные, включая скрытые, в то время как innerText может быть подвержен влиянию стилей CSS. Если вам требуется найти скрытый текст, то лучше всего использовать textContent.

Умелое управление сборниками узлов

Когда работаете с большим объемом информации, например, с параграфами статьи, методы getElementsByTagName и querySelectorAll становятся незаменимыми союзниками. Они возвращают коллекции элементов, которые удобны для перебора:

JS
Скопировать код
const textToFind = "Искомый запрос";
let matchingElements = [];
document.querySelectorAll('p').forEach(p => {
  if (p.textContent.includes(textToFind)) {
    matchingElements.push(p);
  }
});

console.log(matchingElements);

Из прошлого в будущее: что нам дает jQuery

Помните дни, когда jQuery брал верх за счёт селектора :contains()? Он предложил простой способ для текстового поиска:

JS
Скопировать код
const myElement = $("*:contains('Точный текст')")[0];
console.log(myElement); // И вот напоминание о былых временах.

Помните, что :contains() учитывает регистр, так что учтите этот нюанс во время своего поиска.

Визуализация 🎬

Представьте себе, что в огромной библиотеке вам нужно найти одну уникальную книгу, исходя из определённого текста внутри неё:

Markdown
Скопировать код
Библиотека 📚: [Книга1, Книга2, Книга3, ..., КнигаН]

Текст: "Секрет успеха — начать."

Проходя рядами, наша задача — отыскать нужную нам книгу:

Markdown
Скопировать код
🔍📖: Книга1 -> Не она
🔍📖: Книга2 -> Всё ещё не она
🔍📖: Книга3 -> Вот она! ✨

В итоге вы получите элемент, как будто искали его через innerText:

JS
Скопировать код
let foundElement;
document.querySelectorAll('*').forEach(el => {
  if (el.textContent.trim() === "Секрет успеха — начать.") {
    foundElement = el;
  }
});

В нашем примере каждая книга соответствует элементу DOM, а поиск нужного текста аналогичен получению элементов через innerText.

Обзор краевых сценариев

Сценарий 1: Нормализация текста для точного поиска

При поиске текста не забывайте об устранении не должны мешать неприятные пробелы и переносы строк, чтобы форматирование ни в коем случае не помешало найти нужные данные.

JS
Скопировать код
let searchText = " Мой текст ";
searchText = searchText.trim().replace(/\s+/g, ' ');

Сценарий 2: Соответствие требованиям старых браузеров

Для поддержки старых браузеров возможно потребуется использовать транспиляторы, такие как Babel, особенно если они не поддерживают такие методы как document.evaluate().

Сценарий 3: Создание собственной функции поиска

Создание своего способа получения элементов, наподобие getElementsByText, существенно ускорит процесс поиска по определённым тегам или классам:

JS
Скопировать код
function getElementsByText(text, tag = '*') {
  let foundElements = [];
  for (let el of document.getElementsByTagName(tag)) {
    if (el.textContent.trim() === text) {
      foundElements.push(el);
    }
  }
  return foundElements;
}

Сценарий 4: Использование оператора расширения для NodeList

Современный JavaScript позволяет преобразовывать NodeList в массив, что упрощает выполнение фильтрации и работы с элементами:

JS
Скопировать код
const allParagraphs = [...document.querySelectorAll('p')];
const matchingParagraphs = allParagraphs.filter(p => p.textContent.includes('Этот пудинг зачарован.'));

Полезные материалы 📚

  1. Document: метод querySelector() – Web APIs | MDN — Подробное руководство по применению метода .querySelector() для поиска элементов в DOM.
  2. javascript – Наиболее эффективный способ конвертации HTMLCollection в массив – Stack Overflow — Рекомендации по работе с коллекциями узлов в JavaScript.
  3. Поиск: методы getElement, querySelector — Мощный обзор методов выбора элементов в DOM, включая getElement* и querySelector*.
  4. Selectors Level 4 — Обсуждение передовых CSS-селекторов для работы с DOM.
  5. javascript – Где лучше всего разместить теги <script> в HTML-разметке? – Stack Overflow — Рекомендации по оптимальному размещению тегов <script> в HTML-разметке.
  6. Современное состояние HTML5 форм | CSS-Tricks — Обзор возможностей и функций HTML5-форм.